{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Title: #Maximum LCCI"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Difficulty: #Easy"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Category Title: #LCCI"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Tag Slug: #bit-manipulation #brainteaser #math"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Name Translated: #位运算 #脑筋急转弯 #数学"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solution Name: maximum"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Translated Title: #最大数值"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Translated Content:\n",
    "<p>编写一个方法，找出两个数字<code>a</code>和<code>b</code>中最大的那一个。不得使用if-else或其他比较运算符。</p>\n",
    "<p><strong>示例：</strong></p>\n",
    "<pre><strong>输入：</strong> a = 1, b = 2\n",
    "<strong>输出：</strong> 2\n",
    "</pre>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Description: [maximum-lcci](https://leetcode.cn/problems/maximum-lcci/description/)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solutions: [maximum-lcci](https://leetcode.cn/problems/maximum-lcci/solutions/)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_cases = ['2147483647\\n-2147483648']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumCost(self, n: int, highways: List[List[int]], k: int) -> int:\n",
    "        if k >= n:\n",
    "            return -1\n",
    "        g = defaultdict(list)\n",
    "        for a, b, cost in highways:\n",
    "            g[a].append((b, cost))\n",
    "            g[b].append((a, cost))\n",
    "        f = [[-inf] * n for _ in range(1 << n)]\n",
    "        for i in range(n):\n",
    "            f[1 << i][i] = 0\n",
    "        ans = -1\n",
    "        for i in range(1 << n):\n",
    "            for j in range(n):\n",
    "                if i >> j & 1:\n",
    "                    for h, cost in g[j]:\n",
    "                        if i >> h & 1:\n",
    "                            f[i][j] = max(f[i][j], f[i ^ (1 << j)][h] + cost)\n",
    "                if i.bit_count() == k + 1:\n",
    "                    ans = max(ans, f[i][j])\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import math\n",
    "from typing import List\n",
    "from collections import defaultdict,deque\n",
    "from functools import lru_cache\n",
    "class Solution:\n",
    "    def maximumCost(self, n: int, highways: List[List[int]], k: int) -> int:\n",
    "        \"\"\"\n",
    "\n",
    "        :param n:\n",
    "        :param highways:\n",
    "        :param k:\n",
    "        :return:\n",
    "        \"\"\"\n",
    "        m1 = defaultdict(list)\n",
    "        for i in highways:\n",
    "            m1[i[0]].append((i[1], i[2]))\n",
    "            m1[i[1]].append((i[0], i[2]))\n",
    "\n",
    "        @lru_cache(None)\n",
    "        def check_max(start, used):\n",
    "            if len(used) == k + 1:\n",
    "                return 0\n",
    "\n",
    "            ans = -math.inf\n",
    "            for i in m1[start]:\n",
    "                if i[0] not in used:\n",
    "                    ans = max(ans, i[1] + check_max(i[0], used.union({i[0]})))\n",
    "            return ans\n",
    "\n",
    "        ans = -1\n",
    "        for i in range(n):\n",
    "            ans1 = check_max(i, frozenset({i}))\n",
    "            ans = max(ans, ans1)\n",
    "        return ans\n",
    "\n",
    "\n",
    "a = Solution()\n",
    "print(a.maximumCost( n = 4, highways = [[0,1,3],[2,3,2]], k = 2))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import math\n",
    "from typing import List\n",
    "from collections import defaultdict,deque\n",
    "from functools import lru_cache\n",
    "class Solution:\n",
    "    def maximumCost(self, n: int, highways: List[List[int]], k: int) -> int:\n",
    "        \"\"\"\n",
    "\n",
    "        :param n:\n",
    "        :param highways:\n",
    "        :param k:\n",
    "        :return:\n",
    "        \"\"\"\n",
    "        m1 = defaultdict(list)\n",
    "        for i in highways:\n",
    "            m1[i[0]].append((i[1], i[2]))\n",
    "            m1[i[1]].append((i[0], i[2]))\n",
    "\n",
    "        @lru_cache(None)\n",
    "        def check_max(start, used):\n",
    "            if len(used) == k + 1:\n",
    "                return 0\n",
    "\n",
    "            ans = -math.inf\n",
    "            for i in m1[start]:\n",
    "                if i[0] not in used:\n",
    "                    ans = max(ans, i[1] + check_max(i[0], used.union({i[0]})))\n",
    "            return ans\n",
    "\n",
    "        ans = -1\n",
    "        for i in range(n):\n",
    "            ans1 = check_max(i, frozenset({i}))\n",
    "            ans = max(ans, ans1)\n",
    "        return ans\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumCost(self, n: int, highways: List[List[int]], k: int) -> int:\n",
    "        graph = defaultdict(dict)\n",
    "        for a, b, c in highways:\n",
    "            graph[a][b] = c\n",
    "            graph[b][a] = c\n",
    "\n",
    "        @lru_cache(None)\n",
    "        def dfs(cur, explored):\n",
    "            if explored.bit_count() == k + 1:\n",
    "                return 0\n",
    "\n",
    "            ans = -inf\n",
    "            for other, v in graph[cur].items():\n",
    "                if not explored & (o := 1 << other):\n",
    "                    ans = max(ans, dfs(other, explored | o) + v)\n",
    "            return ans\n",
    "\n",
    "        return max(-1, max(dfs(i, 1 << i) for i in range(n)))\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumCount(self, nums: List[int]) -> int:\n",
    "        sz = len(nums)\n",
    "        nnegative = bisect.bisect_left(nums, 0)\n",
    "        npositive = sz - bisect.bisect_right(nums, 0)\n",
    "        result = max(nnegative, npositive)\n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumCount(self, nums: List[int]) -> int:\n",
    "        return max(sum(i < 0 for i in nums), sum(i > 0 for i in nums))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumCount(self, nums: List[int]) -> int:\n",
    "        pos = neg = 0\n",
    "        for num in nums:\n",
    "            if num > 0:\n",
    "                pos += 1\n",
    "            elif num < 0:\n",
    "                neg += 1\n",
    "        return max(pos, neg)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumCount(self, nums: List[int]) -> int:\n",
    "        l, r = bisect_left(nums, 0), bisect_right(nums, 0)\n",
    "        return max(l, len(nums) - r)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumCount(self, nums: List[int]) -> int:\n",
    "        pos, neg = 0, 0\n",
    "        n = len(nums)\n",
    "\n",
    "        def lower_bound(check) -> int:\n",
    "            left, right = 0, n - 1\n",
    "            while left < right:\n",
    "                mid = left + (right - left) // 2\n",
    "                if check(mid):\n",
    "                    right = mid\n",
    "                else:\n",
    "                    left = mid + 1\n",
    "            \n",
    "            return left if check(left) else n\n",
    "\n",
    "        def upper_bound(check) -> int:\n",
    "            left, right = 0, n - 1\n",
    "            while left < right:\n",
    "                mid = left + (right - left + 1) // 2\n",
    "                if check(mid):\n",
    "                    left = mid\n",
    "                else:\n",
    "                    right = mid - 1\n",
    "            \n",
    "            return left if check(left) else n\n",
    "\n",
    "        pos = n - lower_bound(lambda mid : nums[mid] > 0)\n",
    "        # print('pos = ', pos)\n",
    "        neg = upper_bound(lambda mid : nums[mid]<0) + 1\n",
    "        neg = 0 if neg > n else neg\n",
    "        # print('neg = ', neg)\n",
    "        return max(pos, neg)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from typing import List, Tuple, Optional\n",
    "from collections import defaultdict, Counter\n",
    "from sortedcontainers import SortedList\n",
    "\n",
    "MOD = int(1e9 + 7)\n",
    "INF = int(1e20)\n",
    "\n",
    "# 给你一个按 非递减顺序 排列的数组 nums ，返回正整数数目和负整数数目中的最大值。\n",
    "\n",
    "# 换句话讲，如果 nums 中正整数的数目是 pos ，而负整数的数目是 neg ，返回 pos 和 neg二者中的最大值。\n",
    "# 注意：0 既不是正整数也不是负整数。\n",
    "class Solution:\n",
    "    def maximumCount(self, nums: List[int]) -> int:\n",
    "        pos = sum(1 for i in nums if i > 0)\n",
    "        neg = sum(1 for i in nums if i < 0)\n",
    "        return max(pos, neg)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumCount(self, nums: List[int]) -> int:\n",
    "        pos,neg = 0,0\n",
    "        for i in range(len(nums)):\n",
    "            if nums[i] < 0: neg += 1\n",
    "            elif nums[i] > 0: pos += 1\n",
    "        return max(neg,pos)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumCount(self, nums: List[int]) -> int:\n",
    "        max_neg = 0\n",
    "        max_pos = 0\n",
    "\n",
    "        for num in nums:\n",
    "            if num < 0:\n",
    "                max_neg += 1\n",
    "            elif num > 0:\n",
    "                max_pos += 1\n",
    "        return max(max_neg, max_pos)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumCount(self, nums: List[int]) -> int:\n",
    "\n",
    "        return max(sum(i < 0 for i in nums), sum(i > 0 for i in nums))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        res = -1\n",
    "        for i in range(len(nums)):\n",
    "            for j in nums[i+1:]:\n",
    "                if nums[i] < j:\n",
    "                    res = max(res, j-nums[i])\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        minn, ans = max(nums)+1, 0\n",
    "        for num in nums:\n",
    "            minn, ans = min(minn, num), max(ans, num-minn)\n",
    "        return ans if ans > 0 else -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        res = 0\n",
    "        for i in range(len(nums) - 1):\n",
    "            for j in range(i + 1, len(nums)):\n",
    "                res = max(res, nums[j] - nums[i])\n",
    "        if res == 0: return -1\n",
    "        else: return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        ans, premin = -1, nums[0]\n",
    "        for i in range(1, len(nums)):\n",
    "            if nums[i] > premin:\n",
    "                ans = max(ans, nums[i] - premin)\n",
    "            else:\n",
    "                premin = nums[i]\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        res=-1\n",
    "        min_nums=nums[0]\n",
    "        for num in nums:\n",
    "            if num<=min_nums:\n",
    "                min_nums=num\n",
    "                continue\n",
    "            elif num-min_nums>res:\n",
    "                res=num-min_nums\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        m, ans = inf, 0\n",
    "        for num in nums:\n",
    "            m, ans = min(num, m), max(ans, num - m)\n",
    "        return ans if ans > 0 else -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        res = []\n",
    "        ans = 0\n",
    "        min_num = nums[0]\n",
    "        for i in range(n):\n",
    "            if nums[i] < min_num:\n",
    "                min_num = nums[i]\n",
    "            ans_ = nums[i] - min_num\n",
    "            if ans_ > ans:\n",
    "                ans = ans_\n",
    "        if ans == 0:\n",
    "            return -1\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        i,j = 0,1\n",
    "        l = len(nums)-1\n",
    "        ans = 0\n",
    "        while j<=l:\n",
    "            while j<l and nums[j]>=nums[i]:\n",
    "                ans = max([ans,nums[j]-nums[i]])\n",
    "                j +=1 \n",
    "            ans = max([ans,nums[j]-nums[i]])\n",
    "            i = j\n",
    "            j +=1\n",
    "        return ans if ans>0 else -1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        def findMax(lst, n):\n",
    "            ma, m = 0, 0\n",
    "            for i in range(len(lst)):\n",
    "                if lst[i] > ma:\n",
    "                    ma = lst[i]\n",
    "                    m = i\n",
    "            return ma, m + n\n",
    "\n",
    "        def findMin(lst):\n",
    "            mi = float(\"INF\")\n",
    "            for i in range(len(lst)):\n",
    "                if lst[i] < mi:\n",
    "                    mi = lst[i]\n",
    "            return mi\n",
    "\n",
    "        ans = -1\n",
    "        j = -1\n",
    "        while j < len(nums):\n",
    "            max_n, max_i = findMax(nums[j + 1:], j + 1)\n",
    "            min_n = findMin(nums[j + 1: max_i])\n",
    "            ans = max(ans, max_n - min_n)\n",
    "            j = max_i\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        res=-1\n",
    "        min_num=nums[0]\n",
    "        n=len(nums)\n",
    "        for i in range(n-1):\n",
    "            min_num=min(min_num,nums[i])\n",
    "            diff=nums[i+1]-min_num\n",
    "            if diff>0:\n",
    "                res=max(res,diff)\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        ans,premin = -1,nums[0]\n",
    "        for i in range(1,n):\n",
    "            if nums[i]>premin:\n",
    "                ans = max(ans,nums[i]-premin)\n",
    "            else:\n",
    "                premin = nums[i]\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import math\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        maxd=-1\n",
    "        for i in range(len(nums)):\n",
    "            for j in range(i+1,len(nums)):\n",
    "                if nums[i]<nums[j]:\n",
    "                    maxd=max(maxd,nums[j]-nums[i])\n",
    "        return maxd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        nnums = [9,4,3,2]\n",
    "        n = len(nums)\n",
    "        res = []\n",
    "        min_num = nums[0]\n",
    "        for i in range(n):\n",
    "            if nums[i] < min_num:\n",
    "                min_num = nums[i]\n",
    "            ans = nums[i] - min_num\n",
    "            res.append(ans)\n",
    "        if max(res) == 0:\n",
    "            return -1\n",
    "        else:\n",
    "            return max(res)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        ma=-1\n",
    "        mi=nums[0]\n",
    "        for i in range(1,len(nums)):\n",
    "            if nums[i]>mi:\n",
    "                ma=max(ma,nums[i]-mi)\n",
    "            else:mi=nums[i]\n",
    "        return ma"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        ans=-1\n",
    "        \n",
    "        for i in range(len(nums)):\n",
    "            for j in range(i,len(nums)):\n",
    "                delta=nums[j]-nums[i]\n",
    "                if delta >ans and  delta!=0:\n",
    "                    ans=delta\n",
    "        return ans\n",
    "                    \n",
    "                \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        res = -1\n",
    "        for i in range(len(nums)):\n",
    "            for j in range(i+1,len(nums)):\n",
    "                if nums[j] - nums[i] > 0:\n",
    "                    res = max(res, nums[j]-nums[i])\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        res=-1\n",
    "        n=len(nums)\n",
    "        for i in range(n-1):\n",
    "            for j in range(i+1,n):\n",
    "                diff=nums[j]-nums[i]\n",
    "                if diff>0:\n",
    "                    res=max(diff,res)\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        res = -1\n",
    "        \n",
    "        for i in range(len(nums) - 1):\n",
    "            for j in range(i + 1, len(nums)):\n",
    "                tmp = nums[j] - nums[i]\n",
    "                if nums[j] > nums[i] and tmp > res: \n",
    "                    res = tmp\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        res = []\n",
    "        ans = 0\n",
    "        min_num = nums[0]\n",
    "        for i in range(n):\n",
    "            if nums[i] < min_num:\n",
    "                min_num = nums[i]\n",
    "            ans_ = nums[i] - min_num\n",
    "            if ans_ > ans:\n",
    "                ans = ans_\n",
    "        if ans == 0:\n",
    "            return -1\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        ans, premin = -1, nums[0]\n",
    "        for i in range(1, n):\n",
    "            if nums[i] > premin:\n",
    "                ans = max(ans, nums[i]-premin)\n",
    "            else:\n",
    "                premin = nums[i]\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        res = -1\n",
    "        min_num = nums[0]\n",
    "        n = len(nums)\n",
    "        for i in range(n-1):\n",
    "            min_num = min(min_num,nums[i])\n",
    "\n",
    "            diff = nums[i+1] - min_num\n",
    "            if diff > 0:\n",
    "                res = max(res, diff)\n",
    "        return res\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        res = 0\n",
    "        m = inf\n",
    "        for num in nums:\n",
    "            m = min(num,m)\n",
    "            if num - m > res:\n",
    "                res = num - m\n",
    "        return res if res>0 else -1\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        res = -1\n",
    "        \n",
    "        for i in range(len(nums) - 1):\n",
    "            for j in range(i + 1, len(nums)):\n",
    "                tmp = nums[j] - nums[i]\n",
    "                if nums[j] > nums[i] and tmp > res: \n",
    "                    res = tmp\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        ans = -1\n",
    "        for i in range(len(nums)):\n",
    "            for j in range(i + 1, len(nums)):\n",
    "                if nums[j] > nums[i]:\n",
    "                    ans = max(ans, nums[j] - nums[i])\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        low = min(nums[0], nums[1])\n",
    "\n",
    "        high = max(-1, nums[1] - nums[0])\n",
    "\n",
    "        for i in range(2, len(nums)):\n",
    "\n",
    "            high = max(high, nums[i] - low)\n",
    "\n",
    "            low = min(low, nums[i])\n",
    "\n",
    "        if high == 0:\n",
    "\n",
    "            return -1\n",
    "\n",
    "        return high\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        ans = -1\n",
    "        for i in range(len(nums)):\n",
    "            a = max(nums[i:])\n",
    "            if a > nums[i]:\n",
    "                ans = max(ans, a - nums[i])\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        return -1 if (n := len(nums)) and 1 > (r := max(nums[j] - nums[i] for i in range(n) for j in range(i + 1, n))) else r"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        m, ans = inf, 0\n",
    "        for num in nums:\n",
    "            m, ans = min(num, m), max(ans, num - m)\n",
    "        return ans if ans > 0 else -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        a = -1\n",
    "        n = len(nums)\n",
    "        for i in range(n):\n",
    "            for j in range(i+1,n):\n",
    "                if nums[j] - nums[i] > a:\n",
    "                    a = nums[j] - nums[i]\n",
    "        return a if a!=0 else -1 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        res = -1\n",
    "        for i in range(n):\n",
    "            for j in range(i + 1, n):\n",
    "                if nums[j] > nums[i]:\n",
    "                    res = max(res, nums[j] - nums[i])\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        flag = True \n",
    "        max = 0\n",
    "        for i in range(len(nums)):\n",
    "            for j in range(i,len(nums)):\n",
    "                if nums[i]<nums[j]:\n",
    "                    flag = False\n",
    "                    differ = nums[j]-nums[i]\n",
    "                    if differ>max:\n",
    "                        max = differ\n",
    "        if not flag and max !=0:\n",
    "            return max\n",
    "        else:\n",
    "            return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums):\n",
    "        n = len(nums)\n",
    "        max_diff = -1\n",
    "\n",
    "        for i in range(n-1):\n",
    "            for j in range(i+1, n):\n",
    "                if nums[i] < nums[j]:\n",
    "                    diff = nums[j] - nums[i]\n",
    "                    max_diff = max(max_diff, diff)\n",
    "\n",
    "        return max_diff\n",
    "\n",
    "# 示例输入\n",
    "nums = [7,1,5,4]\n",
    "\n",
    "# 创建 Solution 类的实例\n",
    "solution = Solution()\n",
    "\n",
    "# 调用方法计算最大差值\n",
    "result = solution.maximumDifference(nums)\n",
    "\n",
    "# 输出结果\n",
    "print(result)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        max_diff = -1\n",
    "        for i in range(len(nums)):\n",
    "            for j in range(i+1,len(nums)):\n",
    "                if nums[j]- nums[i] > max_diff and nums[j]- nums[i]:\n",
    "                    max_diff =  nums[j]- nums[i]\n",
    "        return max_diff"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        l = len(nums)\n",
    "        r = -1\n",
    "        for i in range(l):\n",
    "            for j in range(i+1, l):\n",
    "                if nums[j] - nums[i] > r and nums[j] > nums[i]:\n",
    "                    r = nums[j] - nums[i]\n",
    "        return r"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        INF = float('inf')\n",
    "        minv = INF\n",
    "        ans = -INF\n",
    "        \n",
    "        for num in nums:\n",
    "            if minv < num:\n",
    "                ans = max(ans, num - minv)\n",
    "            minv = min(minv, num)\n",
    "        if ans == -INF:\n",
    "            ans = -1 \n",
    "        return ans \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        ans = -1\n",
    "        for i, x in enumerate(nums):\n",
    "            for y in nums[i + 1:]:\n",
    "                if y > x:\n",
    "                    ans = max(y - x, ans)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        ans = -1\n",
    "        n = len(nums)\n",
    "        for i in range(0,n-1):\n",
    "            for j in range(i,n):\n",
    "                if nums[i] < nums[j]:\n",
    "                    tmp = nums[j] - nums[i]\n",
    "                    if tmp > ans:\n",
    "                        ans = tmp\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        a=c=d=0\n",
    "        b=1000000001\n",
    "        for i in nums:\n",
    "            if i<=a:\n",
    "                d+=1\n",
    "            a=i\n",
    "            b=min(b,i)\n",
    "            c=max(c,a-b)\n",
    "        if d==len(nums)-1:\n",
    "            return -1\n",
    "        else:\n",
    "            return c"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        result = 0\n",
    "\n",
    "        for i in range(len(nums) - 1):\n",
    "\n",
    "            result = max(result, max(nums[i+1:]) - nums[i])\n",
    "        \n",
    "        if result == 0:\n",
    "            return -1\n",
    "        else:\n",
    "            return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        m, ans = inf, 0\n",
    "        for num in nums:\n",
    "            m, ans = min(num, m), max(ans, num - m)\n",
    "        return ans if ans > 0 else -1\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        if nums==sorted(nums,reverse=True):\n",
    "            return -1\n",
    "        c=0\n",
    "        for i in range(len(nums)):\n",
    "            for j in range(i+1,len(nums)):\n",
    "                if nums[i]>=nums[j]:\n",
    "                    continue\n",
    "                else:\n",
    "                    c=max(c,nums[j]-nums[i])\n",
    "        return c"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        min_ = nums[0]\n",
    "        res = -1\n",
    "        for i in range(1,len(nums)):\n",
    "            if nums[i] > min_:\n",
    "                res = max(res,nums[i]-min_)\n",
    "            else:\n",
    "                min_ = nums[i]\n",
    "        return res\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        ans = -1\n",
    "        for x in range(len(nums) - 1):\n",
    "            for y in range(x + 1, len(nums)):\n",
    "                if nums[y] > nums[x]:\n",
    "                    ans = max(ans, nums[y] - nums[x])\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        left = nums[0]\n",
    "        diff = -1\n",
    "        for i in range(1, len(nums)):\n",
    "            if left < nums[i]:\n",
    "                diff = max(diff, (nums[i] - left))\n",
    "            else:\n",
    "                left = nums[i]\n",
    "        return diff\n",
    "\n",
    "    # def maximumDifference(self, nums: List[int]) -> int:\n",
    "    #     n = len(nums)\n",
    "    #     diff = float('-inf')\n",
    "    #     for i in range(n):\n",
    "    #         for j in range(i + 1, n):\n",
    "    #             if nums[i] > nums[j]:\n",
    "    #                 break\n",
    "    #             diff = max(diff, (nums[j] - nums[i]))\n",
    "\n",
    "    #     return diff if diff > 0 else -1\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        ans = -1\n",
    "        pre = nums[0]\n",
    "        for i in range(1,n):\n",
    "            if nums[i] > pre:\n",
    "                diff = nums[i] - pre\n",
    "                if ans < diff:\n",
    "                    ans = diff\n",
    "            else:\n",
    "                pre = nums[i]\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        m, ans = inf, 0\n",
    "        for num in nums:\n",
    "            m, ans = min(num, m), max(ans, num - m)\n",
    "        return ans if ans > 0 else -1\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        ret,last=-1,nums[-1]\n",
    "        for i in range(len(nums)-2,-1,-1):\n",
    "            if nums[i]<last:\n",
    "                ret=max(last-nums[i],ret)\n",
    "            last=max(last,nums[i])\n",
    "        return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        a = sorted(nums, reverse=True)\n",
    "        if nums == a:\n",
    "            return -1\n",
    "        res = float('-inf')\n",
    "        for i in range(len(nums)):\n",
    "            for j in range(i, len(nums)):\n",
    "                res1 = nums[j] - nums[i]\n",
    "                res = max(res, res1)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        ans,premin=-1,nums[0]\n",
    "        for i in range(1,n):\n",
    "                if nums[i]>premin:\n",
    "                    ans=max(ans,nums[i]-premin)\n",
    "                else:\n",
    "                    premin=nums[i]\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        maxs = -1\n",
    "        for i in range(len(nums) - 1):\n",
    "            # 只有大于0，才行\n",
    "            if max(nums[i+1:]) - nums[i] > 0:\n",
    "                maxs = max(maxs, max(nums[i+1:]) - nums[i])\n",
    "        return maxs\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        ans,n1 = 0,nums[0]\n",
    "        for n in nums[1:]:\n",
    "            if n > n1:\n",
    "                ans = max(ans,n-n1)\n",
    "            n1 = min(n1,n)\n",
    "        return ans if ans != 0 else -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        dmax, vmin = -1, float('inf')\n",
    "        for i in range(n):\n",
    "            if nums[i] > vmin:\n",
    "                dmax = max(dmax, nums[i] - vmin)\n",
    "            else:\n",
    "                vmin = nums[i]\n",
    "        return dmax\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        res, max_, min_, tmp = 0, -1, nums[0], 1\n",
    "        while tmp < len(nums):\n",
    "            min_ = min(min_, nums[res])\n",
    "            max_ = max(max_, nums[tmp] - min_)\n",
    "            res += 1\n",
    "            tmp += 1\n",
    "        if max_ == 0:\n",
    "            max_ = -1\n",
    "        return max_\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        res = -1\n",
    "        \n",
    "        for i in range(len(nums) - 1):\n",
    "            for j in range(i + 1, len(nums)):\n",
    "                tmp = nums[j] - nums[i]\n",
    "                if nums[j] > nums[i] and tmp > res: \n",
    "                    res = tmp\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        ans, premin = -1, nums[0]\n",
    "        for i in range(1, len(nums)):\n",
    "            if nums[i] > premin: ans = max(ans, nums[i] - premin)\n",
    "            else: premin = nums[i]\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        if not nums:\n",
    "            return -1\n",
    "        ans = -1\n",
    "        pre = nums[0]\n",
    "        for i in range(1, len(nums)):\n",
    "            if nums[i] > pre:\n",
    "                ans = max(ans, nums[i] - pre)\n",
    "            \n",
    "            else:\n",
    "                pre = nums[i]\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        s=sorted(nums,reverse=True)\n",
    "        if nums==s:\n",
    "            return -1\n",
    "        else:\n",
    "            n=0\n",
    "            for i in range(len(nums)-1):\n",
    "                for j in range(i+1,len(nums)):\n",
    "                    if nums[j]>nums[i]:\n",
    "                        n=max(n,nums[j]-nums[i])\n",
    "            return n "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        ans, premin = -1, nums[0]\n",
    "\n",
    "        for i in range(1, n):\n",
    "            if nums[i] > premin:\n",
    "                ans = max(ans, nums[i] - premin)\n",
    "            else:\n",
    "                premin = nums[i]\n",
    "        \n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "\n",
    "        INF = float('inf')\n",
    "\n",
    "        minv = INF\n",
    "\n",
    "        ans = -INF\n",
    "\n",
    "        for num in nums:\n",
    "\n",
    "            if minv < num:\n",
    "\n",
    "                ans = max(ans, num - minv)\n",
    "\n",
    "            minv = min(minv, num)\n",
    "\n",
    "        if ans == -INF:\n",
    "\n",
    "            ans = -1 \n",
    "\n",
    "        return ans \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        res, tmp = -1, nums[0]\n",
    "        for num in nums[1:]:\n",
    "            if num > tmp:\n",
    "                res = max(num-tmp, res)\n",
    "            else:\n",
    "                tmp = num\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        ans = -1\n",
    "        m = nums[0]\n",
    "        for x in nums[1:]:\n",
    "            if m != x:\n",
    "                ans = max(ans, x - m)\n",
    "            m = min(m, x)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        ans = -1\n",
    "        n = len(nums)\n",
    "        for i in range(n):\n",
    "            for j in range(i+1, n):\n",
    "                if nums[j] > nums[i]:\n",
    "                    ans = max(ans, nums[j]-nums[i])\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        res = []\n",
    "        ans = 0\n",
    "        min_num = nums[0]\n",
    "        for i in range(n):\n",
    "            if nums[i] < min_num:\n",
    "                min_num = nums[i]\n",
    "            ans_ = nums[i] - min_num\n",
    "            if ans_ > ans:\n",
    "                ans = ans_\n",
    "        if ans == 0:\n",
    "            return -1\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        nnums = [9,4,3,2]\n",
    "        n = len(nums)\n",
    "        res = []\n",
    "        min_num = nums[0]\n",
    "        for i in range(n):\n",
    "            if nums[i] < min_num:\n",
    "                min_num = nums[i]\n",
    "            ans = nums[i] - min_num\n",
    "            res.append(ans)\n",
    "        res = list(set(res))\n",
    "        res.sort()\n",
    "        if res[-1] == 0:\n",
    "            return -1\n",
    "        else:\n",
    "            return res[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        maxdiff = -1\n",
    "        for i in range(len(nums) - 1):\n",
    "            for j in range(i + 1, len(nums)):\n",
    "                if nums[j] - nums[i] > 0:\n",
    "                    maxdiff = max(maxdiff, nums[j] - nums[i])\n",
    "        return maxdiff"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        ans = nums[1] - nums[0]  # 初始化答案为第一个数与第二个数的差值\n",
    "        l = len(nums)  # 获取数组长度\n",
    "        \n",
    "        # 遍历数组，计算相邻两个数之间的差值\n",
    "        for i in range(l - 1):\n",
    "            for j in range(i + 1, l):\n",
    "                ans = max(ans, nums[j] - nums[i])  # 更新答案为所有相邻数之差的最大值\n",
    "                \n",
    "        # 检查答案是否小于等于0\n",
    "        if ans <= 0:\n",
    "            return -1\n",
    "        else:\n",
    "            return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        ans, premin = -1, nums[0]\n",
    "\n",
    "        for i in range(1, n):\n",
    "            if nums[i] > premin:\n",
    "                ans = max(ans, nums[i] - premin)\n",
    "            else:\n",
    "                premin = nums[i]\n",
    "        \n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        res = -1\n",
    "        min_num = nums[0]\n",
    "        n = len(nums)\n",
    "        for i in range(n-1):\n",
    "            min_num = min(min_num,nums[i])\n",
    "\n",
    "            diff = nums[i+1] - min_num\n",
    "            if diff > 0:\n",
    "                res = max(res, diff)\n",
    "        return res\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "  def maximumDifference(self, nums: List[int]) -> int:\n",
    "    ans,n = -1,len(nums)\n",
    "    for i in range(n-1):\n",
    "      for j in range(i+1,n):\n",
    "        ans = max(ans, nums[j]-nums[i])\n",
    "        if not ans: ans =-1\n",
    "    return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        left = 0\n",
    "        ans = 0\n",
    "        for right in range(1, len(nums)):\n",
    "            diff = nums[right] - nums[left]\n",
    "            if diff > ans:\n",
    "                ans = diff\n",
    "            if nums[right] < nums[left]:\n",
    "                left = right\n",
    "        if ans == 0:\n",
    "            return -1\n",
    "        else:\n",
    "            return ans\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        maxs = -1\n",
    "        for i in range(len(nums)):\n",
    "            for j in range(i+1,len(nums)):\n",
    "                if nums[j] - nums[i] > 0 :\n",
    "                    maxs = max(maxs,nums[j] - nums[i])  \n",
    "        return maxs\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        cur_min = -1\n",
    "        for i in range(n):\n",
    "            for j in range(i + 1, n):\n",
    "                if nums[j] - nums[i] > 0:\n",
    "                    cur_min = max(nums[j] - nums[i], cur_min)\n",
    "        return cur_min"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        ret,last=-1,nums[-1]\n",
    "        for i in range(len(nums)-2,-1,-1):\n",
    "            if nums[i]<last:\n",
    "                ret=max(last-nums[i],ret)\n",
    "            last=max(last,nums[i])\n",
    "        return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        ans, premin = -1, nums[0]\n",
    "\n",
    "        for i in range(1, n):\n",
    "            if nums[i] > premin:\n",
    "                ans = max(ans, nums[i] - premin)\n",
    "            else:\n",
    "                premin = nums[i]\n",
    "        \n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        ans = -1\n",
    "        pre = nums[0]\n",
    "        for num in nums[1:]:\n",
    "            if num > pre:\n",
    "                if num-pre > ans:\n",
    "                    ans = num-pre\n",
    "            else:\n",
    "                pre= num\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        return max(nums[j] - nums[i] for i in range(n) for j in range(i, n)) or -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumDifference(self, nums: List[int]) -> int:\n",
    "        min_num = float('inf')  # 初始化最小值为正无穷大\n",
    "        max_diff = -1  # 初始化最大差值为负数\n",
    "\n",
    "        for num in nums:\n",
    "            if num < min_num:\n",
    "                min_num = num\n",
    "            diff = num - min_num\n",
    "            if diff > max_diff:\n",
    "                max_diff = diff\n",
    "\n",
    "        return max_diff if max_diff > 0 else -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        retVal = 1\n",
    "\n",
    "        arr.sort()\n",
    "        arrSize = len(arr)\n",
    "        for i in range(1, arrSize):\n",
    "            if arr[i] - retVal >= 1:\n",
    "                retVal += 1\n",
    "\n",
    "        return retVal"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: list[int]) -> int:\n",
    "        arr.sort()\n",
    "        arr[0] = 1\n",
    "        for i in range(1, len(arr)):\n",
    "            if not abs(arr[i]-arr[i-1]) <= 1:\n",
    "                arr[i] = arr[i-1]+1\n",
    "        return arr[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        limit = 1\n",
    "        for num in sorted(arr)[1:]:\n",
    "            limit = min(limit + 1, num)\n",
    "        return limit\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        arr.sort()\n",
    "        t = 1\n",
    "        for x in arr:\n",
    "            if x < t:\n",
    "                continue\n",
    "            t+=1\n",
    "        return t-1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        arr.sort()\n",
    "        arr[0], n = 1, len(arr)\n",
    "        for i in range(1, n):\n",
    "            if arr[i] - arr[i - 1] > 1:\n",
    "                arr[i] = arr[i - 1] + 1\n",
    "        return arr[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        arr.sort()\n",
    "        arr[0] = 1\n",
    "        for i in range(1, len(arr)):\n",
    "            if arr[i] - arr[i - 1] > 1:\n",
    "                arr[i] = arr[i - 1] + 1\n",
    "        return arr[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "\n",
    "        # 奇怪的題目...\n",
    "        \"\"\"\n",
    "        arr.sort()\n",
    "\n",
    "        # 第一個元素一定要等於 1\n",
    "        if arr[0] != 1:\n",
    "            arr[0] = 1\n",
    "\n",
    "        max_num = arr[0]\n",
    "        for i in range(1, len(arr)):\n",
    "            diff = abs(arr[i] - arr[i-1])\n",
    "            if diff <= 1:\n",
    "                max_num = max(max_num, arr[i])\n",
    "            else:\n",
    "                arr[i] = arr[i - 1] + 1\n",
    "                max_num = max(max_num, arr[i])\n",
    "        return max_num\n",
    "        \"\"\"\n",
    "        \n",
    "        # 比較簡潔的寫法\n",
    "        arr.sort()\n",
    "        max_num = arr[0] = 1\n",
    "\n",
    "        for i in range(1, len(arr)):\n",
    "            if arr[i] - arr[i - 1] > 1:\n",
    "                arr[i] = arr[i - 1] + 1\n",
    "            max_num = max(max_num, arr[i])\n",
    "        return max_num "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        arr.sort()\n",
    "        n = len(arr)\n",
    "        arr[0] = 1\n",
    "        for i in range(1, n):\n",
    "            arr[i] = min(arr[i - 1] + 1, arr[i])\n",
    "        return arr[n - 1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        arr.sort()\n",
    "        arr[0] = 1\n",
    "        for i in range(1, len(arr)):\n",
    "            if arr[i] - arr[i-1] > 1:\n",
    "                arr[i] = arr[i-1] + 1\n",
    "        return arr[-1]\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        limit=1\n",
    "        for i in sorted(arr)[1:]:\n",
    "            limit=min(limit+1,i)\n",
    "        return limit\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        arr.sort()\n",
    "        index = 0\n",
    "        for i in arr:\n",
    "            if i > index:\n",
    "                index += 1\n",
    "        return index\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        retVal = 1\n",
    "\n",
    "        arr.sort()\n",
    "\n",
    "        arrSize = len(arr)\n",
    "        for i in range(1, arrSize):\n",
    "            if arr[i] - retVal >= 1:\n",
    "                retVal += 1\n",
    "\n",
    "        return retVal"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        n = len(arr)\n",
    "        cnt = [False] + [True] * n\n",
    "        arr.sort()\n",
    "        i = 1\n",
    "        for x in arr:\n",
    "            if i <= x:\n",
    "                cnt[i] = True\n",
    "                i += 1\n",
    "        return i - 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        # 不用考虑原数组元素，只需构造与原数组一样长度的新数组即可\n",
    "        n = len(arr)\n",
    "        arr.sort()\n",
    "        if arr[0] != 1:\n",
    "            arr[0] = 1\n",
    "        for i in range(1, n):\n",
    "            tm = arr[i]-arr[i-1]\n",
    "            if tm != 0:\n",
    "                arr[i] = arr[i-1] + 1\n",
    "        return arr[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "\n",
    "        # 奇怪的題目...\n",
    "        \"\"\"\n",
    "        arr.sort()\n",
    "\n",
    "        # 第一個元素一定要等於 1\n",
    "        if arr[0] != 1:\n",
    "            arr[0] = 1\n",
    "\n",
    "        max_num = arr[0]\n",
    "        for i in range(1, len(arr)):\n",
    "            diff = abs(arr[i] - arr[i-1])\n",
    "            if diff <= 1:\n",
    "                max_num = max(max_num, arr[i])\n",
    "            else:\n",
    "                arr[i] = arr[i - 1] + 1\n",
    "                max_num = max(max_num, arr[i])\n",
    "        return max_num\n",
    "        \"\"\"\n",
    "        \n",
    "        # 比較簡潔的寫法\n",
    "        arr.sort()\n",
    "        max_num = arr[0] = 1\n",
    "\n",
    "        for i in range(1, len(arr)):\n",
    "            if arr[i] - arr[i - 1] > 1:\n",
    "                arr[i] = arr[i - 1] + 1\n",
    "            max_num = max(max_num, arr[i])\n",
    "        return max_num "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "\n",
    "        arr.sort()\n",
    "\n",
    "        if arr[0] != 1:\n",
    "            arr[0] = 1\n",
    "\n",
    "        max_num = arr[0]\n",
    "        for i in range(1, len(arr)):\n",
    "            diff = abs(arr[i] - arr[i-1])\n",
    "            if diff <= 1:\n",
    "                max_num = max(max_num, arr[i])\n",
    "            else:\n",
    "                arr[i] = arr[i - 1] + 1\n",
    "                max_num = max(max_num, arr[i])\n",
    "        return max_num\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        arr.sort()\n",
    "        limit = 1\n",
    "        for num in arr[1:]:\n",
    "            limit = min(limit+1, num)\n",
    "        return limit"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        arr.sort()\n",
    "        ans = 0\n",
    "        for i in arr:\n",
    "            if i - ans > 1:\n",
    "                ans += 1\n",
    "            else:\n",
    "                ans = i\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        arr.sort()\n",
    "        if arr[0] != 1:\n",
    "            arr[0] = 1\n",
    "        for i in range(1,len(arr)):\n",
    "            if arr[i] - arr[i - 1] > 1:\n",
    "                arr[i] = arr[i - 1] + 1\n",
    "        return arr[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        arr.sort()\n",
    "        arr[0] = 1\n",
    "        for i in range(1, len(arr)):\n",
    "            if arr[i] - arr[i-1] > 1:\n",
    "                arr[i] = arr[i-1]+1\n",
    "        return arr[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        n = len(arr)\n",
    "        if n==1:\n",
    "            return 1\n",
    "        arr.sort()\n",
    "        if arr[0]!=1:\n",
    "            arr[0] = 1\n",
    "        start = 1\n",
    "        while start<n:\n",
    "            if abs(arr[start]-arr[start-1])<=1:\n",
    "                start += 1\n",
    "            else:\n",
    "                arr[start] = arr[start-1]+1\n",
    "        return arr[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        arr.sort()\n",
    "        n = len(arr)\n",
    "        arr[0] = 1\n",
    "        for i in range(1, n):\n",
    "            if arr[i] - arr[i - 1] > 1:\n",
    "                arr[i] = arr[i - 1] + 1\n",
    "        return arr[n - 1] "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        limit = 1\n",
    "        for num in sorted(arr)[1:]:\n",
    "            limit = min(limit + 1, num)\n",
    "        return limit"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        retVal = 0\n",
    "\n",
    "        arr.sort()\n",
    "        retVal = 1\n",
    "\n",
    "        arrSize = len(arr)\n",
    "        for i in range(1, arrSize):\n",
    "            if arr[i] - retVal >= 1:\n",
    "                retVal += 1\n",
    "\n",
    "        return retVal"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        counter = [0 for _ in range(len(arr)+1)]\n",
    "        for i, v in enumerate(arr):\n",
    "            if v >= len(counter):\n",
    "                v = len(counter)-1\n",
    "            counter[v] += 1\n",
    "        miss = 0\n",
    "        res = 0\n",
    "        for i in range(1, len(counter)):\n",
    "            v = counter[i]\n",
    "            if v == 0:\n",
    "                miss += 1\n",
    "            else:\n",
    "                if v > miss:\n",
    "                    miss = 0\n",
    "                    res = i\n",
    "                else:\n",
    "                    res += v\n",
    "                    miss -= v       \n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        n = len(arr)\n",
    "        arr.sort()\n",
    "        arr[0] = 1\n",
    "        for i in range(n-1):\n",
    "            if arr[i+1] - arr[i] > 1:\n",
    "                arr[i+1] = arr[i] + 1\n",
    "        \n",
    "        return arr[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        arr.sort()\n",
    "        i = 1\n",
    "        n = len(arr)\n",
    "        arr[0] = 1\n",
    "        while i < n:\n",
    "            if arr[i] - arr[i-1] <= 1:\n",
    "                i += 1\n",
    "            else:\n",
    "                arr[i] = arr[i-1] + 1\n",
    "        return arr[n-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        n = len(arr)\n",
    "        arr.sort()\n",
    "        arr[0] = 1\n",
    "        for i in range(n-1):\n",
    "            if arr[i+1] - arr[i] > 1:\n",
    "                arr[i+1] = arr[i] + 1\n",
    "        \n",
    "        return arr[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        n = len(arr)\n",
    "        if n == 1:\n",
    "            return 1\n",
    "        arr.sort()\n",
    "        arr[0] = 1\n",
    "        for i in range(1, n):\n",
    "            if arr[i]>arr[i-1]:\n",
    "                arr[i] = arr[i-1] + 1\n",
    "        return arr[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "\n",
    "        # 奇怪的題目...\n",
    "        \"\"\"\n",
    "        arr.sort()\n",
    "\n",
    "        # 第一個元素一定要等於 1\n",
    "        if arr[0] != 1:\n",
    "            arr[0] = 1\n",
    "\n",
    "        max_num = arr[0]\n",
    "        for i in range(1, len(arr)):\n",
    "            diff = abs(arr[i] - arr[i-1])\n",
    "            if diff <= 1:\n",
    "                max_num = max(max_num, arr[i])\n",
    "            else:\n",
    "                arr[i] = arr[i - 1] + 1\n",
    "                max_num = max(max_num, arr[i])\n",
    "        return max_num\n",
    "        \"\"\"\n",
    "        \n",
    "        # 比較簡潔的寫法\n",
    "        arr.sort()\n",
    "        max_num = arr[0] = 1\n",
    "\n",
    "        for i in range(1, len(arr)):\n",
    "            if arr[i] - arr[i - 1] > 1:\n",
    "                arr[i] = arr[i - 1] + 1\n",
    "            max_num = max(max_num, arr[i])\n",
    "        return max_num "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "\n",
    "        # 奇怪的題目...\n",
    "        \"\"\"\n",
    "        arr.sort()\n",
    "\n",
    "        # 第一個元素一定要等於 1\n",
    "        if arr[0] != 1:\n",
    "            arr[0] = 1\n",
    "\n",
    "        max_num = arr[0]\n",
    "        for i in range(1, len(arr)):\n",
    "            diff = abs(arr[i] - arr[i-1])\n",
    "            if diff <= 1:\n",
    "                max_num = max(max_num, arr[i])\n",
    "            else:\n",
    "                arr[i] = arr[i - 1] + 1\n",
    "                max_num = max(max_num, arr[i])\n",
    "        return max_num\n",
    "        \"\"\"\n",
    "        \n",
    "        # 比較簡潔的寫法\n",
    "        arr.sort()\n",
    "        max_num = arr[0] = 1\n",
    "\n",
    "        for i in range(1, len(arr)):\n",
    "            if arr[i] - arr[i - 1] > 1:\n",
    "                arr[i] = arr[i - 1] + 1\n",
    "            max_num = max(max_num, arr[i])\n",
    "        return max_num "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        arr.sort()\n",
    "        n = len(arr)\n",
    "        arr[0] = 1\n",
    "        for i in range(1,n):\n",
    "            if arr[i] > arr[i-1] + 1:\n",
    "                arr[i] = arr[i-1] + 1\n",
    "        return arr[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        limit = 1\n",
    "        for num in sorted(arr)[1:]:\n",
    "            limit = min(limit + 1, num)\n",
    "        return limit\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        n = len(arr)\n",
    "        arr.sort()\n",
    "        arr[0] = 1\n",
    "        for i in range(n-1):\n",
    "            if arr[i+1] - arr[i] > 1:\n",
    "                arr[i+1] = arr[i] + 1\n",
    "        \n",
    "        return arr[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        n = len(arr)\n",
    "        arr.sort()\n",
    "        arr[0] = 1\n",
    "        for i in range(1, n):\n",
    "            if arr[i] - arr[i - 1] > 1:\n",
    "                arr[i] = arr[i - 1] + 1\n",
    "        return arr[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "\n",
    "        # 奇怪的題目...\n",
    "        \"\"\"\n",
    "        arr.sort()\n",
    "\n",
    "        # 第一個元素一定要等於 1\n",
    "        if arr[0] != 1:\n",
    "            arr[0] = 1\n",
    "\n",
    "        max_num = arr[0]\n",
    "        for i in range(1, len(arr)):\n",
    "            diff = abs(arr[i] - arr[i-1])\n",
    "            if diff <= 1:\n",
    "                max_num = max(max_num, arr[i])\n",
    "            else:\n",
    "                arr[i] = arr[i - 1] + 1\n",
    "                max_num = max(max_num, arr[i])\n",
    "        return max_num\n",
    "        \"\"\"\n",
    "\n",
    "        # 比較簡潔的寫法\n",
    "        \"\"\"\n",
    "        arr.sort()\n",
    "        max_num = arr[0] = 1\n",
    "\n",
    "        for i in range(1, len(arr)):\n",
    "            if arr[i] - arr[i - 1] > 1:\n",
    "                arr[i] = arr[i - 1] + 1\n",
    "            max_num = max(max_num, arr[i])\n",
    "        return max_num\n",
    "        \"\"\"\n",
    "\n",
    "        # 不用更改 arr 內容\n",
    "        arr.sort()\n",
    "        prev = 0\n",
    "        for i in arr:\n",
    "            prev = min(prev + 1, i)\n",
    "        return prev"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        arr.sort()\n",
    "        arr[0] = 1\n",
    "        for i in range(1, len(arr)):\n",
    "            arr[i] = min(arr[i], arr[i-1] + 1)\n",
    "        return arr[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        arr.sort()\n",
    "        cur = 1\n",
    "        arr[0] = 1\n",
    "        for num in arr:\n",
    "            if num <= cur:\n",
    "                continue\n",
    "            else:\n",
    "                cur+=1\n",
    "        return cur"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        arr.sort()\n",
    "        j = len(arr) - 1\n",
    "        for i, x in enumerate(arr):\n",
    "            if i >= j + 1: return i\n",
    "            if x < i + 1:\n",
    "                if j > i and arr[j] >= i + 1:\n",
    "                    j -= 1\n",
    "                else:\n",
    "                    return i\n",
    "        return len(arr)\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        arr.sort()\n",
    "        if arr[0] != 1:\n",
    "            arr[0] = 1\n",
    "        for i in range(1, len(arr)):\n",
    "            if arr[i] > arr[i - 1] + 1:\n",
    "                arr[i] = arr[i - 1] + 1\n",
    "        return arr[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        arr.sort()\n",
    "        base=0\n",
    "        for i,v in enumerate(arr):\n",
    "            if v>base:\n",
    "                base+=1\n",
    "        return base"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        n = len(arr)\n",
    "        arr.sort()\n",
    "        pre = 1\n",
    "        for i in range(1, n):\n",
    "            if arr[i] == pre:\n",
    "                continue\n",
    "            pre += 1\n",
    "        return pre \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        ideal = len(arr)\n",
    "        arr.sort()\n",
    "        gap = 0\n",
    "        # 核心在于查看当前数与1,2,3升序数组相差值gap为多少。这个gap直接影响到最终输出的最大值。\n",
    "        for i, v in enumerate(arr, 1):\n",
    "            gap = max(gap, i - v)\n",
    "        return ideal - gap\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from typing import List\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        arr.sort()\n",
    "        arr[0] = 1\n",
    "        for i in range(1,len(arr)) :\n",
    "            if arr[i] -1 > arr[i-1] :\n",
    "                arr[i] = arr[i-1] + 1\n",
    "            pass\n",
    "        return arr[-1]\n",
    "        pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        arr.sort()\n",
    "        arr[0]=1\n",
    "        for i in range(1,len(arr)):\n",
    "            if arr[i]>arr[i-1]:\n",
    "                arr[i]=arr[i-1]+1\n",
    "        return arr[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        n = len(arr)\n",
    "        arr.sort()\n",
    "        arr[0] = 1\n",
    "        for i in range(1, n):\n",
    "            arr[i] = min(arr[i - 1] + 1, arr[i])\n",
    "\n",
    "        return arr[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        arr.sort()\n",
    "        arr[0] = 1\n",
    "        for i in range(1, len(arr)) :\n",
    "            if arr[i] > arr[i-1]+1 :\n",
    "                arr[i] = arr[i-1]+1\n",
    "        \n",
    "        return arr[-1]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        limit = 1\n",
    "        for num in sorted(arr)[1:]:\n",
    "            limit = min(limit + 1, num)\n",
    "        return limit\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        # limit = 1\n",
    "        # for num in sorted(arr)[1:]:\n",
    "        #     limit = min(limit + 1, num)\n",
    "        # return limit\n",
    "\n",
    "        #维护一个记录1到n分别有多少个的数组即可\n",
    "        #第一个循环是计数，统计arr里面从1到n每个数有多少个(大于n的统一看做n，因为答案最大才是n，再大的数也得减小到n); 第二个循环是从1到n搭建，对于第i个台阶，我们不可能超过它(因为每次变化最多为1)，该台阶能为limit做出的贡献有它的个数(这里主要是为了补足前面空缺的台阶)。比如说你有n个n，1到n-1一个没有，limit到最后一个循环仍然能取到n，这就好比用了n-1个n去补充前面的所有台阶的感觉，但是不管怎么填充，也不能超过自己的最高上限。这就好比你有100个1，和有1个1是一样的\n",
    "        n = len(arr)\n",
    "        cnts = [0] * (n + 1)\n",
    "        for num in arr:\n",
    "            cnts[min(num, n)] += 1\n",
    "        limit = 0\n",
    "        for i in range(1, n + 1):\n",
    "            #下一个台阶\n",
    "            limit = min(i, limit + cnts[i])\n",
    "        return limit"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        arr.sort()\n",
    "        arr[0]=1\n",
    "        for i in range(1, len(arr)):\n",
    "            if arr[i]-arr[i-1]>1:\n",
    "                arr[i] = arr[i-1]+1\n",
    "        return arr[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        arr.sort()\n",
    "        n = len(arr)\n",
    "        ans = 0\n",
    "        for i in range(n):\n",
    "            ans = min(i + 1, arr[i], ans + 1)\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        arr.sort()\n",
    "        \n",
    "        arr[0] = 1\n",
    "        for i in range(1, len(arr)):\n",
    "            if arr[i] >= arr[i - 1] + 1:\n",
    "                arr[i] = arr[i - 1] + 1\n",
    "\n",
    "        return arr[-1]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        n = len(arr)\n",
    "        arr.sort()\n",
    "        arr[0] = 1\n",
    "        for i in range(1, n):\n",
    "            if arr[i] - arr[i - 1] > 1:\n",
    "                arr[i] = arr[i - 1] + 1\n",
    "        return arr[n - 1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        n = len(arr)\n",
    "        mx = max(arr)\n",
    "        arr.sort()\n",
    "        for i in range(n):\n",
    "            if i == 0:\n",
    "                arr[i] = 1\n",
    "            else:\n",
    "                if arr[i] - arr[i - 1] > 1:\n",
    "                    arr[i] = arr[i - 1] + 1\n",
    "        return arr[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        arr.sort()\n",
    "        arr[0]=1\n",
    "        for i in range(1,len(arr)):\n",
    "            arr[i]=min(arr[i-1]+1,arr[i])\n",
    "        return arr[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        cnts = [0] * (len(arr) + 1)\n",
    "\n",
    "        for a in arr:\n",
    "            cnts[min(a, len(arr))] += 1\n",
    "\n",
    "        i = 1\n",
    "        j = 1\n",
    "\n",
    "        while True:\n",
    "            while j < len(cnts) and cnts[j] == 0:\n",
    "                j += 1\n",
    "            \n",
    "            if j == len(cnts):\n",
    "                break\n",
    "            \n",
    "            while j < len(cnts) and cnts[j] != 0 and i <= j:\n",
    "                i += 1\n",
    "                cnts[j] -= 1\n",
    "            \n",
    "            if j < len(cnts) and cnts[j] != 0 and i > j:\n",
    "                j += 1\n",
    "\n",
    "        return i - 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        arr.sort()\n",
    "        limit = 1\n",
    "        n = len(arr)\n",
    "        for i in range(1, n):\n",
    "            limit = min(limit + 1, arr[i])\n",
    "        return limit\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        N = len(arr)\n",
    "        cnts = [0 for _ in range(N + 1)]\n",
    "        for num in arr:\n",
    "            cnts[min(num, N)] += 1\n",
    "        \n",
    "        miss = 0\n",
    "        for idx in range(1, N + 1):\n",
    "            cnt = cnts[idx]\n",
    "            if cnt == 0:\n",
    "                miss += 1\n",
    "            else:\n",
    "                miss = max(0, miss - (cnt - 1)) # we can use (cnt - 1) nums to be decreased to fill the missing nums\n",
    "\n",
    "        return N - miss\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        arr.sort()\n",
    "        n = len(arr)\n",
    "        if arr[0]!=1:\n",
    "            arr[0] = 1\n",
    "        for i in range(1,n):\n",
    "            if arr[i]-arr[i-1]>1:\n",
    "                arr[i] = arr[i-1]+1\n",
    "        return arr[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        arr.sort()\n",
    "        arr[0] = 1\n",
    "\n",
    "        for i in range(1, len(arr)):\n",
    "            arr[i] = min(arr[i], arr[i-1] + 1)\n",
    "        \n",
    "        return arr[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        arr = sorted(arr)\n",
    "        res = 1\n",
    "        l = len(arr)\n",
    "        prev = 0\n",
    "        for i in range(l):\n",
    "            if arr[i]>i+1 or arr[i]-prev>1:\n",
    "                arr[i] = min(i+1, prev+1)\n",
    "            prev = arr[i]\n",
    "            res = max(res, prev)\n",
    "            \n",
    "        return res\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        a=[1]\n",
    "        for n in sorted(arr)[1:]:a.append(min(a[-1]+1,n))\n",
    "        return a[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        arr = sorted(arr)\n",
    "        arr[0] = 1\n",
    "        for i in range(1, len(arr)):\n",
    "            arr[i] = min(arr[i - 1] + 1, arr[i])\n",
    "        return arr[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        sort_arr = sorted(arr)\n",
    "        sort_arr[0]=1\n",
    "\n",
    "        for i in range(1,len(sort_arr)):\n",
    "            if sort_arr[i]-sort_arr[i-1] > 1:\n",
    "                sort_arr[i]=sort_arr[i-1]+1\n",
    "\n",
    "        return sort_arr[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:\n",
    "        mapping = {}\n",
    "        for a in arr:\n",
    "            if(a not in mapping):\n",
    "                mapping[a] = 1\n",
    "            else:\n",
    "                mapping[a] += 1\n",
    "        nums = sorted(list(mapping.keys()))\n",
    "        curmax = 0\n",
    "        for num in nums:\n",
    "            if(mapping[num] >= num - curmax):\n",
    "                curmax = num \n",
    "            else:\n",
    "                curmax += mapping[num]\n",
    "        return curmax"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "test = [i * i for i in range(1, 101)]\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        ans = 0\n",
    "        for i in range(1, len(nums) + 1):\n",
    "            res = 0\n",
    "            for j in test:\n",
    "                if i * j <= len(nums):\n",
    "                    res += nums[i * j - 1]\n",
    "                else:\n",
    "                    break\n",
    "            ans = max(ans, res)\n",
    "        return ans\n",
    "                \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, A: List[int]) -> int:\n",
    "        return max(sum(A[d * x * x - 1]\n",
    "                       for x in range(1, isqrt(len(A) // d) + 1))\n",
    "                   for d in range(1, len(A) + 1))\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, A: List[int]) -> int:\n",
    "        return max(sum(A[d * x * x - 1]\n",
    "                       for x in range(1, isqrt(len(A) // d) + 1))\n",
    "                   for d in range(1, len(A) + 1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        i = 1\n",
    "        n = len(nums)\n",
    "        ls = []\n",
    "        while i*i <= n:\n",
    "            ls.append(i*i)\n",
    "            i += 1\n",
    "        res = max(sum(nums[i-1] for i in ls),max(nums))\n",
    "        #print(ls,res)\n",
    "        for j in range(2,n):\n",
    "            o = []\n",
    "            for i in range(len(ls)):\n",
    "                if ls[i]*j<=n:o.append(ls[i]*j)\n",
    "                else:break\n",
    "            #print(o)\n",
    "            if len(o)==1:break\n",
    "            #print(o,nums)\n",
    "            res = max(sum(nums[i-1] for i in o),res)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import os\n",
    "from typing import *\n",
    "from functools import lru_cache\n",
    "from collections import Counter\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        idxs = []\n",
    "        for i in range(1, n+1):\n",
    "            r = i * i\n",
    "            if r > n:\n",
    "                break\n",
    "            idxs.append(r)\n",
    "\n",
    "        res = 0\n",
    "        for i in range(1, n+1):\n",
    "            s = 0\n",
    "            for idx in idxs:\n",
    "                ni = idx * i\n",
    "                if ni > n:\n",
    "                    break\n",
    "                s += nums[ni-1]\n",
    "            res = max(res, s)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from math import sqrt\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        def core(num):\n",
    "            if num < 4:\n",
    "                return num\n",
    "\n",
    "            i = 2\n",
    "            while i < sqrt(num) + 1:\n",
    "                if (num / pow(i,2)) % 1 == 0:\n",
    "                    num = num // pow(i,2)\n",
    "                    i = 2\n",
    "                    continue\n",
    "                i += 1\n",
    "            return num\n",
    "        \n",
    "        ans = [0] * (len(nums) + 1)\n",
    "        for i in range(len(nums)):\n",
    "            ans[core(i+1)] += nums[i]\n",
    "        return max(ans)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        square = [i * i for i in range(1, 200) if i * i <= n]\n",
    "        # print(square)\n",
    "        ans = max(nums)\n",
    "        for i in range(1, n+1):\n",
    "            tmp = 0\n",
    "            for sq in square:\n",
    "                if i * sq > n:\n",
    "                    break\n",
    "                tmp += nums[i * sq - 1]\n",
    "            \n",
    "            ans = max(ans, tmp)\n",
    "        return ans\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        l0 = []\n",
    "        for i in range(1, n + 1):\n",
    "            if i * i > n:\n",
    "                break\n",
    "            l0.append(i * i)\n",
    "        ans = 0\n",
    "        for j in range(1, n + 1):\n",
    "            tmp = 0\n",
    "            for i in l0:\n",
    "                if j * i > n:\n",
    "                    break\n",
    "                tmp += nums[j * i - 1]\n",
    "            ans = max(ans, tmp)   \n",
    "        return ans\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        s=[]\n",
    "        \n",
    "        n=len(nums)\n",
    "        # d={}\n",
    "        # lh=[1]\n",
    "        maxa=0\n",
    "        a=0\n",
    "        for j in range(1,n+1):\n",
    "            if j**2<=n:\n",
    "                a=a+nums[j**2-1]\n",
    "                s.append(j**2)\n",
    "        maxa=a\n",
    "\n",
    "        for i in range(2,n+1):\n",
    "            if i in s:\n",
    "                continue\n",
    "            # d[i]=[i]\n",
    "            a=nums[i-1]\n",
    "            for j in range(2,int(sqrt((n/i)))+1):\n",
    "                if True:                                               \n",
    "                    if (i*j*j<=n):\n",
    "                        # d[i].append(i*j*j)  \n",
    "                        a=a+nums[i*j*j-1]     \n",
    "            maxa=max(maxa,a)             \n",
    "                        \n",
    "        ll=[]\n",
    "        # for i in d:\n",
    "            \n",
    "        #     p=list(set(d[i]))\n",
    "        #     maxa=max(maxa,sum([nums[j-1]for j in p]))\n",
    "\n",
    "        # maxa=max(maxa,a)     \n",
    "            \n",
    "        # print(maxa,n,d,s,a)\n",
    "        return maxa\n",
    "               \n",
    "       "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "sq = [i**2 for i in range(1,101)]\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        def getprem(num):\n",
    "            n1, n2 =[], []\n",
    "            for i in range(1, int(num**0.5)):\n",
    "                if num%i == 0:\n",
    "                    n1.append(i)\n",
    "                    n2.append(num//i)\n",
    "            return n1, n2\n",
    "        multi = 1\n",
    "        ans = max(nums)\n",
    "        while(multi*4 <=len(nums)):\n",
    "            ans = max(ans , sum(nums[i*multi-1] for i in sq if i*multi<=len(nums)))\n",
    "            multi+=1\n",
    "        for j in sq:\n",
    "            if j>len(nums)**2:\n",
    "                break\n",
    "            n1, n2 = getprem(j)\n",
    "            for i, k in zip(n1,n2):\n",
    "                if i-1>=len(nums) or k-1>=len(nums):\n",
    "                    continue\n",
    "                ans = max(ans, nums[i-1]+nums[k-1])\n",
    "        return ans\n",
    "        \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        ans = 0\n",
    "        for i in range(n):\n",
    "            res = 0\n",
    "            for j in count(1):\n",
    "                idx = (i + 1) * j * j - 1\n",
    "                if idx >= n: break\n",
    "                res += nums[idx]\n",
    "            ans = max(ans, res)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "\n",
    "        n = len(nums)\n",
    "        ans = 0\n",
    "        for i in range(1,n+1):\n",
    "            s = 0\n",
    "            for j in range(1,isqrt(n//i)+1):\n",
    "                s+=nums[i*j*j-1]\n",
    "            ans = max(ans,s)\n",
    "        \n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        # 枚举\n",
    "        pass\n",
    "        ans = 0\n",
    "        n = len(nums)\n",
    "        for i in range(1, n + 1):\n",
    "            #i 为当前最大值\n",
    "            s = 0\n",
    "            # i * j * j 为同组数据，IJJ *iJJ 肯定是满足完全平方\n",
    "            for j in range(1, isqrt(n // i) + 1):\n",
    "                s += nums[i * j * j - 1]  # -1 是因为数组下标从 0 开始\n",
    "            ans = max(ans, s)\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# core(x) x除去「偶数数量质因数」后 的质因数的乘积\n",
    "# 一组数字中每对元素的乘积都是一个完全平方数 每个数的core是相同的\n",
    "# core(1): 1, 4, 9, 16, 25, 36...\n",
    "# core(2): 2*1, 2*4, 2*9, 2*16...\n",
    "# core(3): 3*1, 3*4, 3*9, 3*16...\n",
    "# core(i): i*1, i*4, i*9, i*16...\n",
    "# i * j * j <= n   ->    j <= isqrt(n // i)\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        ans = 0\n",
    "        for i in range(1, n + 1): # 可能是质数 所以枚举到n\n",
    "            s = 0\n",
    "            for j in range(1, isqrt(n // i) + 1):\n",
    "                s += nums[i * j * j - 1]\n",
    "            ans = max(ans, s)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        def core(n):\n",
    "            res = 1\n",
    "            for i in range(2, int(sqrt(n)) + 1):\n",
    "                e = 0\n",
    "                while n % i == 0:\n",
    "                    e ^= 1\n",
    "                    n //= i\n",
    "                if e:\n",
    "                    res *= i\n",
    "            if n > 1:\n",
    "                res *= n\n",
    "            return res\n",
    "        ans = [0 for _ in range(len(nums) + 1)]\n",
    "        for i, v in enumerate(nums, 1):\n",
    "            ans[core(i)] += v\n",
    "        return max(ans)\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from typing import List\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        \"\"\"\n",
    "\n",
    "        :param nums:\n",
    "        :return:\n",
    "        \"\"\"\n",
    "        len1 = len(nums)\n",
    "        ret = []\n",
    "        for i in range(1, 1000):\n",
    "            cnt = 1\n",
    "            ret2 = []\n",
    "            gap = i\n",
    "            while gap * cnt ** 2 <= len1:\n",
    "                ret2.append(cnt ** 2 * gap)\n",
    "                cnt += 1\n",
    "            if len(ret2) == 0:\n",
    "                break\n",
    "            ret.append(ret2)\n",
    "        s1 = 0\n",
    "        for i in ret:\n",
    "            v1 = 0\n",
    "            for x in i:\n",
    "                v1 += nums[x - 1]\n",
    "            s1 = max(s1, v1)\n",
    "        return s1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from typing import List\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        \"\"\"\n",
    "\n",
    "        :param nums:\n",
    "        :return:\n",
    "        \"\"\"\n",
    "        len1 = len(nums)\n",
    "        ret = []\n",
    "        for i in range(1, 1000):\n",
    "            cnt = 1\n",
    "            ret2 = []\n",
    "            gap = i\n",
    "            while gap * cnt ** 2 <= len1:\n",
    "                ret2.append(cnt ** 2 * gap)\n",
    "                cnt += 1\n",
    "            if len(ret2) == 0:\n",
    "                break\n",
    "            ret.append(ret2)\n",
    "        s1 = max(nums)\n",
    "        for i in ret:\n",
    "            v1 = 0\n",
    "            for x in i:\n",
    "                v1 += nums[x - 1]\n",
    "            s1 = max(s1, v1)\n",
    "        return s1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        s=[0]*(len(nums)+1)\n",
    "        for i,x in enumerate(nums,1):\n",
    "            s[core[i]]+=x\n",
    "        return max(s)\n",
    "\n",
    "MX=10001\n",
    "core=[0]*MX\n",
    "for i in range(1,MX):\n",
    "    if core[i]==0:\n",
    "        for j in range(1,isqrt(MX//i)+1):\n",
    "            core[i*j*j]=i\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# core(x) x除去「偶数数量质因数」后 的质因数的乘积\n",
    "# 一组数字中每对元素的乘积都是一个完全平方数 每个数的core是相同的\n",
    "core = [1] * (10 ** 4 + 1)\n",
    "for x in range(2, 10 ** 4 + 1):\n",
    "    num = x\n",
    "    for y in range(2, isqrt(x) + 1):\n",
    "        cnt = 0\n",
    "        while num % y == 0:\n",
    "            cnt += 1\n",
    "            num //= y\n",
    "        if cnt % 2 == 1: core[x] *= y\n",
    "    if num > 1: core[x] *= num\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        ans = [0] * (n + 1) # 索引:core值 值:累积和\n",
    "        for i, x in enumerate(nums, 1):\n",
    "            ans[core[i]] += x\n",
    "        return max(ans)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        result = int(math.sqrt(n))\n",
    "        ls = []\n",
    "        lst=[]\n",
    "        ans = 0\n",
    "        for i in range(1,result*2+1):\n",
    "            if i*i<=n:\n",
    "                ans+=nums[i*i-1]\n",
    "                lst.append(i*i)\n",
    "            if i in lst:\n",
    "                continue\n",
    "            k=1\n",
    "            if i>1:\n",
    "                for j in range(2,result*2):\n",
    "                    k=i*(j**2)\n",
    "                    while k<=n:\n",
    "                        if (i,k) not in ls:\n",
    "                            ls.append((i,k))\n",
    "                        k=k*(j**2)\n",
    "        ex = {}\n",
    "        for m,(x,y) in enumerate(ls):\n",
    "            if str(x) in ex:\n",
    "                ex[str(x)] = ex.get(str(x))+nums[y-1]\n",
    "            else:\n",
    "                ex[str(x)] = nums[x-1]+nums[y-1]\n",
    "        for key in ex:\n",
    "            ans = max(ans,ex.get(key))\n",
    "\n",
    "        ans = max(ans,max(nums))\n",
    "        return ans\n",
    "\n",
    "\n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "mx = 10001\n",
    "core = [0 for _ in range(mx)]\n",
    "for i in range(1, mx):\n",
    "    if core[i]==0: # i 不含完全平方因子，可以作为core值\n",
    "        for j in range(1, isqrt(mx//i)+1):\n",
    "            core[i*j*j] = i\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        s = [0 for _ in range(n+1)]\n",
    "        for i, x in enumerate(nums, 1):\n",
    "            s[core[i]] += x \n",
    "        return max(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        result = int(math.sqrt(n))\n",
    "        ls = []\n",
    "        lst=[]\n",
    "        i_res = []\n",
    "        ans = 0\n",
    "        for i in range(1,result*2+1):\n",
    "            if i*i<=n:\n",
    "                ans+=nums[i*i-1]\n",
    "                lst.append(i*i)\n",
    "            if i in lst:\n",
    "                continue\n",
    "            k=1\n",
    "            if i>1:\n",
    "                for j in range(2,n//2):\n",
    "                    k=i*(j**2)\n",
    "                    while k<=n:\n",
    "                        if (i,k) not in ls:\n",
    "                            ls.append((i,k))\n",
    "                        k=k*(j**2)\n",
    "        print(lst,ls,result,n)\n",
    "        ex = {}\n",
    "        for m,(x,y) in enumerate(ls):\n",
    "            if str(x) in ex:\n",
    "                ex[str(x)] = ex.get(str(x))+nums[y-1]\n",
    "            else:\n",
    "                ex[str(x)] = nums[x-1]+nums[y-1]\n",
    "        for key in ex:\n",
    "            ans = max(ans,ex.get(key))\n",
    "\n",
    "        ans = max(ans,max(nums))\n",
    "        return ans\n",
    "\n",
    "\n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        n=len(nums)\n",
    "        core=[[]]*(n+1)\n",
    "        square=[]\n",
    "        for i in range(1,int(sqrt(n))+1):\n",
    "            square.append(i*i)\n",
    "        ans=0\n",
    "        \n",
    "        for i in range(1,n+1):\n",
    "            temp=0\n",
    "            for x in square:\n",
    "                if i*x>n:\n",
    "                    break\n",
    "                core[i].append(i*x)\n",
    "                temp+=nums[i*x-1]\n",
    "            if temp>ans:\n",
    "                ans=temp\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        data = {}\n",
    "        for i in range(1, n + 1):\n",
    "            x = i\n",
    "            now = 1\n",
    "            for j in range(2, int(sqrt(i)) + 1):\n",
    "                cnt = 0\n",
    "                while x % j == 0:\n",
    "                    cnt ^= 1\n",
    "                    x //= j\n",
    "                if cnt == 1:\n",
    "                    now *= j\n",
    "            if x != 1:\n",
    "                now *= x\n",
    "            if now not in data.keys():\n",
    "                data[now] = nums[i - 1]\n",
    "            else:\n",
    "                data[now] += nums[i - 1]\n",
    "        ans = 0\n",
    "        for key in data.keys():\n",
    "            ans = max(ans, data[key])\n",
    "        return ans\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        \"\"\"\n",
    "        定义core(x)是将x除去完全平方因子后的剩余结果，即x中所有出现次数为奇数的质因子相乘\n",
    "        那么要保证一个组中任意一对元素的乘积都是一个完全平方数，那么要保证这个组的core(x)都是一样的\n",
    "        \"\"\"\n",
    "        def core(x):\n",
    "            ans = 1\n",
    "            p = 2\n",
    "            while p * p <= x:\n",
    "                cnt = 0\n",
    "                while x % p == 0:\n",
    "                    x //= p\n",
    "                    cnt += 1\n",
    "                if cnt & 1:\n",
    "                    ans *= p\n",
    "                p += 1\n",
    "            if x > 1:\n",
    "                ans *= x\n",
    "            return ans\n",
    "        n = len(nums)\n",
    "        memo = defaultdict(int)\n",
    "        for i, x in enumerate(nums, 1):\n",
    "            memo[core(i)] += x\n",
    "        return max(memo.values())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        counter = collections.Counter()\n",
    "        for idx in range(1, n + 1):\n",
    "            p = 1\n",
    "            cur = idx\n",
    "            x = 2 \n",
    "            while x * x <= idx:\n",
    "                if cur % x == 0:\n",
    "                    cnt = 0\n",
    "                    while cur % x == 0:\n",
    "                        cnt ^= 1 \n",
    "                        cur //= x\n",
    "                    if cnt == 1:\n",
    "                        p *= x \n",
    "                x += 1\n",
    "            if idx > 1:\n",
    "                p *= cur \n",
    "            counter[p] += nums[idx - 1] \n",
    "        return max(counter.values())\n",
    "\n",
    "       "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        N = len(nums)\n",
    "\n",
    "        # 查找小于N的所有素数\n",
    "        l_p = [3]\n",
    "        n = 5\n",
    "\n",
    "        while n < N:\n",
    "            for p in l_p:\n",
    "                if n % p == 0:\n",
    "                    break\n",
    "                if p * p > n:\n",
    "                    l_p.append(n)\n",
    "                    break\n",
    "            n += 2\n",
    "\n",
    "        l_p.insert(0, 2)\n",
    "\n",
    "        # 乘以平方数，并求和\n",
    "        def calc(mul):\n",
    "            # print(mul)\n",
    "            l = []\n",
    "            n = 1\n",
    "\n",
    "            while 1:\n",
    "                n2 = n * n * mul\n",
    "                if n2 > N:\n",
    "                    break\n",
    "\n",
    "                n += 1\n",
    "                l.append(n2)\n",
    "\n",
    "            ret = 0\n",
    "            for i in l:\n",
    "                ret += nums[i - 1]\n",
    "            return ret\n",
    "\n",
    "        ret = max(calc(1), max(nums))\n",
    "\n",
    "        # 取n个素数相乘\n",
    "        # 最大值\n",
    "        M = N // 4\n",
    "\n",
    "        def get(n, mul, i):\n",
    "            l = [mul]\n",
    "            for j in range(i, n + i):\n",
    "                l.append(l[-1] * l_p[j])\n",
    "\n",
    "            if l[-1] > M:\n",
    "                return\n",
    "\n",
    "            yield l[-1]\n",
    "\n",
    "            # 每一位往后移\n",
    "            for j in range(n):\n",
    "                yield from get(j + 1, l[n - j - 1], i + n - j)\n",
    "\n",
    "        # print(N, M)\n",
    "\n",
    "        for n in range(1, len(l_p) + 1):\n",
    "            isok = False\n",
    "            for mul in get(n, 1, 0):\n",
    "                isok = True\n",
    "                ret = max(ret, calc(mul))\n",
    "\n",
    "            if not isok:\n",
    "                return ret\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        #算下标\n",
    "        n=len(nums)\n",
    "        t=defaultdict(int)\n",
    "        ans=0\n",
    "        for i in range(1,len(nums)+1):\n",
    "            f=1\n",
    "            j=2\n",
    "            while j*j<=i:\n",
    "                if i%(j*j)==0:\n",
    "                    f=j*j\n",
    "                j+=1\n",
    "            t[i//f]+=nums[i-1]\n",
    "            ans=max(ans,t[i//f])\n",
    "        return ans\n",
    "\n",
    "\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        counter = collections.Counter()\n",
    "        for idx in range(1, n + 1):\n",
    "            p = 1\n",
    "            cur = idx\n",
    "            x = 2 \n",
    "            while x * x <= idx:\n",
    "                if cur % x == 0:\n",
    "                    cnt = 0\n",
    "                    while cur % x == 0:\n",
    "                        cnt ^= 1 \n",
    "                        cur //= x\n",
    "                    if cnt == 1:\n",
    "                        p *= x \n",
    "                x += 1\n",
    "            if idx > 1:\n",
    "                p *= cur \n",
    "            counter[p] += nums[idx - 1] \n",
    "        return max(counter.values())\n",
    "\n",
    "       "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        counter = collections.Counter()\n",
    "        for idx in range(1, n + 1):\n",
    "            p = 1\n",
    "            cur = idx\n",
    "            x = 2 \n",
    "            while x * x <= idx:\n",
    "                if cur % x == 0:\n",
    "                    cnt = 0\n",
    "                    while cur % x == 0:\n",
    "                        cnt ^= 1 \n",
    "                        cur //= x\n",
    "                    if cnt == 1:\n",
    "                        p *= x \n",
    "                x += 1\n",
    "            if idx > 1:\n",
    "                p *= cur \n",
    "            counter[p] += nums[idx - 1] \n",
    "        return max(counter.values())\n",
    "\n",
    "       "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        counter = collections.Counter()\n",
    "        for i in range(1, n + 1):\n",
    "            idx = i\n",
    "            p = 2 \n",
    "            cur = 1\n",
    "            while p * p <= idx:\n",
    "                if idx % p == 0:\n",
    "                    cnt = 0\n",
    "                    while idx % p == 0:\n",
    "                        cnt ^= 1 \n",
    "                        idx //= p \n",
    "                    if cnt == 1:\n",
    "                        cur *= p \n",
    "                p += 1 \n",
    "            if idx > 1:\n",
    "                cur *= idx \n",
    "            counter[cur] += nums[i - 1]\n",
    "        return max(counter.values())\n",
    "                \n",
    "                    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "@cache  # 保存 core(n) 的计算结果，测试用例之间可以复用\n",
    "def core(n: int) -> int:\n",
    "    res = 1\n",
    "    for i in range(2, isqrt(n) + 1):\n",
    "        e = 0\n",
    "        while n % i == 0:\n",
    "            e ^= 1\n",
    "            n //= i\n",
    "        if e:\n",
    "            res *= i\n",
    "    if n > 1:\n",
    "        res *= n\n",
    "    return res\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        s = [0] * (len(nums) + 1)\n",
    "        for i, x in enumerate(nums, 1):\n",
    "            s[core(i)] += x\n",
    "        return max(s)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "@cache  # 保存 core(n) 的计算结果，测试用例之间可以复用\n",
    "def core(n: int) -> int:\n",
    "    res = 1\n",
    "    for i in range(2, isqrt(n) + 1):\n",
    "        e = 0\n",
    "        while n % i == 0:\n",
    "            e ^= 1\n",
    "            n //= i\n",
    "        if e:\n",
    "            res *= i\n",
    "    if n > 1:\n",
    "        res *= n\n",
    "    return res\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        s = [0] * (len(nums) + 1)\n",
    "        for i, x in enumerate(nums, 1):\n",
    "            s[core(i)] += x\n",
    "        return max(s)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "MAX=10**4+5\n",
    "prime=[0 for i in range(MAX)]\n",
    "prime[1]=1\n",
    "for i in range(2,MAX):\n",
    "    if prime[i]==0:\n",
    "        prime[i]=i\n",
    "        for j in range(i+i,MAX,i):\n",
    "            if prime[j]==0:\n",
    "                prime[j]=1\n",
    "            k=j\n",
    "            m=0\n",
    "            while k%i==0:\n",
    "                k//=i\n",
    "                m^=1\n",
    "            if m==1:\n",
    "                prime[j]*=i\n",
    "class Solution:\n",
    "    def maximumSum(self, a: List[int]) -> int:\n",
    "        n=len(a)\n",
    "        ans={}\n",
    "        for i,j in enumerate(a):\n",
    "            ans[prime[i+1]]=ans.get(prime[i+1],0)+j\n",
    "        return max(ans.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "@cache\n",
    "def get(x: int) -> int:\n",
    "    res = 1\n",
    "    for i in range(2, isqrt(x) + 1):\n",
    "        if x % i == 0:\n",
    "            e = 0\n",
    "            while x % i == 0:\n",
    "                e += 1\n",
    "                x //= i\n",
    "            if e % 2 != 0:\n",
    "                res *= i\n",
    "    if x > 1:\n",
    "        res *= x\n",
    "    return res\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        s = [0] * (n + 1)\n",
    "        for i, x in enumerate(nums, 1):\n",
    "            s[get(i)] += x\n",
    "        return max(s)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "@cache  # 保存 core(n) 的计算结果，测试用例之间可以复用\n",
    "def core(n: int) -> int:\n",
    "    res = 1\n",
    "    for i in range(2, isqrt(n) + 1):\n",
    "        e = 0\n",
    "        while n % i == 0:\n",
    "            e ^= 1\n",
    "            n //= i\n",
    "        if e:\n",
    "            res *= i\n",
    "    if n > 1:\n",
    "        res *= n\n",
    "    return res\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        s = [0] * (len(nums) + 1)\n",
    "        for i, x in enumerate(nums, 1):\n",
    "            s[core(i)] += x\n",
    "        return max(s)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "@cache\n",
    "def core(x : int) -> int:\n",
    "    p = 2\n",
    "    k = 0\n",
    "    res = 1\n",
    "    while p <= x:\n",
    "        if x % p == 0:\n",
    "            k += 1\n",
    "            x //= p\n",
    "        else:\n",
    "            if k > 0 and k % 2:\n",
    "                res *= p\n",
    "            k = 0\n",
    "            p += 1\n",
    "    if k > 0 and k % 2:\n",
    "        res *= p\n",
    "    return res\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        s = [0] * (len(nums) + 1)\n",
    "        for i, x in enumerate(nums):\n",
    "            s[core(i + 1)] += x\n",
    "        return max(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        def getPrimeFactors(n: int):\n",
    "            if n <= 1:\n",
    "                return tuple()\n",
    "            primes = Counter()\n",
    "            while n % 2 == 0:\n",
    "                primes[2] = (primes[2] + 1) % 2\n",
    "                n //= 2\n",
    "            for i in range(3, int(sqrt(n)) + 1, 2):\n",
    "                while n % i == 0:\n",
    "                    primes[i] = (primes[i] + 1) % 2\n",
    "                    n //= i\n",
    "            if n > 2:\n",
    "                primes[n] = (primes[n] + 1) % 2\n",
    "            return tuple([k for (k, v) in primes.items() if v > 0])\n",
    "        visited = defaultdict(int)\n",
    "        ans = 0\n",
    "        for i, n in enumerate(nums):\n",
    "            f = getPrimeFactors(i + 1)\n",
    "            ans = max(ans, n)\n",
    "            if f in visited:\n",
    "                ans = max(ans, visited[f] + n)\n",
    "            # print(i, n, f, visited[f], ans)\n",
    "            visited[f] += n\n",
    "        return ans\n",
    "            \n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "@cache\n",
    "def core(n: int) -> int:\n",
    "    res = 1\n",
    "    for i in range(2,isqrt(n) + 1):\n",
    "        e = 0\n",
    "        while n % i == 0:\n",
    "            n //= i\n",
    "            e += 1\n",
    "        if e % 2:\n",
    "            res *= i\n",
    "    res *= n\n",
    "    return res\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        s = [0] * (n + 1)\n",
    "        for i, x in enumerate(nums):\n",
    "            s[core(i + 1)] += x\n",
    "        return max(s)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from functools import cache\n",
    "\n",
    "MAXN = 10001\n",
    "prims = []\n",
    "is_prims = [True] * MAXN\n",
    "min_prim = [None] * MAXN\n",
    "equiv = [None] * MAXN\n",
    "\n",
    "equiv[1] = 1\n",
    "\n",
    "for i in range(2, MAXN):\n",
    "    if is_prims[i]:\n",
    "        prims.append(i)\n",
    "        min_prim[i] = i\n",
    "        equiv[i] = i\n",
    "    for p in prims:\n",
    "        if p > min_prim[i] or p * i >= MAXN:\n",
    "            break\n",
    "        v = p * i\n",
    "        is_prims[v] = False\n",
    "        min_prim[v] = p\n",
    "        if p == min_prim[i]:\n",
    "            equiv[v] = equiv[i // p]\n",
    "        else:\n",
    "            equiv[v] = equiv[i] * p\n",
    "\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        groups = {}\n",
    "        for i in range(1, len(nums) + 1):\n",
    "            e = equiv[i]\n",
    "            groups[e] = groups.get(e, 0) + nums[i - 1]\n",
    "        return max(groups.values())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        #return nums[0]\n",
    "        n = len(nums)\n",
    "        had = Counter()\n",
    "        ans = 0\n",
    "        #先求出n以内（包括n）的所有质数\n",
    "        # isPrime = [True] * (n + 1)\n",
    "        # for i in range(2, int(sqrt(n)) + 1):\n",
    "        #     if not isPrime[i]:\n",
    "        #         continue\n",
    "        #     for x in range(i * i, n + 1, i):\n",
    "        #         isPrime[x] = False\n",
    "        # ans = 0\n",
    "        # for i in range(1, int(sqrt(n)) + 1):\n",
    "        #     ans += nums[i*i-1]\n",
    "\n",
    "        for i in range(n):\n",
    "            minI = i + 1\n",
    "            #对minI进行质数分解\n",
    "            x = minI\n",
    "            base = 2\n",
    "            odd = []\n",
    "              \n",
    "            while base * base <= x:\n",
    "                cnt = 0\n",
    "                if x % base == 0:\n",
    "                    \n",
    "                    while x % base == 0:\n",
    "                        cnt += 1\n",
    "                        x //= base\n",
    "                if cnt % 2 == 1:\n",
    "                    odd.append(base)\n",
    "\n",
    "                base += 1\n",
    "            if x > 1:\n",
    "                odd.append(x)    \n",
    "\n",
    "            if odd == []:\n",
    "                odd = [1]\n",
    "            print(i, odd)\n",
    "            odd = tuple(odd)\n",
    "            had[odd] += nums[i]\n",
    "            \n",
    "        for key in had:\n",
    "            ans = max(ans, had[key])\n",
    "\n",
    "        return ans\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "            \n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        mp = collections.defaultdict(list)\n",
    "        for idx in range(1, len(nums)+1):\n",
    "            i = 2\n",
    "            ii = i*i\n",
    "            x = idx\n",
    "            while ii <= x:\n",
    "                if x % ii == 0:\n",
    "                    x //= ii\n",
    "                    continue\n",
    "                i += 1\n",
    "                ii = i*i\n",
    "            mp[x].append(idx)\n",
    "        res = 0\n",
    "        for k, v in mp.items():\n",
    "            cur = 0\n",
    "            for idx in v:\n",
    "                cur += nums[idx-1]\n",
    "            res = max(res, cur)\n",
    "        return res\n",
    "                \n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Primer(object):\n",
    "    \"\"\"素数相关运算的辅助类\n",
    "\n",
    "    Attributes:\n",
    "        1. n：用素数筛选法提前计算好的最大数\n",
    "        2. primes：n以内的所有素数列表\n",
    "        3. min_prime_factors：每个下标数的最小素因数（最小素因数不存在时为-1）\n",
    "\n",
    "    \"\"\"\n",
    "\n",
    "    @property\n",
    "    def n(self):\n",
    "        return self._n\n",
    "\n",
    "    @property\n",
    "    def primes(self):\n",
    "        return self._primes\n",
    "\n",
    "    @property\n",
    "    def min_prime_factors(self):\n",
    "        return self._min_prime_factors\n",
    "\n",
    "    def __init__(self, n=100):\n",
    "        \"\"\"初始化\n",
    "\n",
    "        生成n以内的所有素数primes，同时得到每个数的最小素因数min_prime_factors\n",
    "\n",
    "        Time Complexity:\n",
    "            O(n)\n",
    "\n",
    "        \"\"\"\n",
    "        primes = []\n",
    "        min_prime_factors = [-1, -1] + [0] * (n - 1)\n",
    "        for i in range(2, n + 1):\n",
    "            if min_prime_factors[i] == 0:\n",
    "                primes.append(i)\n",
    "                min_prime_factors[i] = i\n",
    "            j = 0\n",
    "            while i * primes[j] <= n:\n",
    "                min_prime_factors[i * primes[j]] = primes[j]\n",
    "                if i % primes[j] == 0:\n",
    "                    break\n",
    "                j += 1\n",
    "        self._n = n\n",
    "        self._primes = primes\n",
    "        self._min_prime_factors = min_prime_factors\n",
    "\n",
    "    def _miller_rabin(self, m, seed):\n",
    "        assert m > 2 and (m & 1) == 1, '参数m不能设为%d' % m\n",
    "\n",
    "        k = 0\n",
    "        t = m - 1\n",
    "        while (t & 1) == 1:\n",
    "            t >>= 1\n",
    "            k += 1\n",
    "\n",
    "        a = pow(seed, t, m)\n",
    "        if a == 1 or a == m - 1:\n",
    "            return True\n",
    "        for i in range(k - 1):\n",
    "            a = pow(a, 2, m)\n",
    "            if a == 1:\n",
    "                return False\n",
    "            if a == m - 1:\n",
    "                return True\n",
    "        return False\n",
    "\n",
    "    def is_prime(self, m, k=10):\n",
    "        \"\"\"\n",
    "\n",
    "        Returns:\n",
    "            m是否为素数\n",
    "\n",
    "        Procedure:\n",
    "            1. 若m <= n，使用min_prime_factors直接判定，O(1)\n",
    "            2. 若m <= n * n或m存在n以内的素因子，遍历primes判定，O(len(primes))\n",
    "            3. 若m > n * n且m不存在n以内的素因子，miller_rabin随机算法判定，合数判成素数的错误率小于4^(-k)，O(len(primes) + k*log(n))\n",
    "\n",
    "        \"\"\"\n",
    "        if m <= self.n:\n",
    "            return self.min_prime_factors[m] == m\n",
    "        for p in self.primes:\n",
    "            if m % p == 0:\n",
    "                return False\n",
    "            if p * p > m:\n",
    "                return True\n",
    "        return all((self._miller_rabin(m, i) for i in self.primes[:k]))\n",
    "\n",
    "    def decompose(self, m):\n",
    "        \"\"\"正整数质因子分解\n",
    "\n",
    "        Returns:\n",
    "            [[p1, a1], [p2, a2] ...]，代表m = (p1 ^ a1) * (P2 ^ a2) * ...\n",
    "            举例：输入40，返回[[2, 3], [5, 1]]\n",
    "\n",
    "        Attention:\n",
    "            若m存在不只一个大于n的素因子，将命中断言，无法进一步分解\n",
    "\n",
    "        Time Complexity:\n",
    "            O(len(primes))\n",
    "\n",
    "        \"\"\"\n",
    "        assert m > 0, '参数m不能设为%d' % m\n",
    "\n",
    "        if m == 1:\n",
    "            return deque()\n",
    "        if m <= self.n:\n",
    "            t = self.min_prime_factors[m]\n",
    "            ans = self.decompose(m // t)\n",
    "            if ans and ans[0][0] == t:\n",
    "                ans[0][1] += 1\n",
    "            else:\n",
    "                ans.appendleft([t, 1])\n",
    "            return ans\n",
    "        ans = deque()\n",
    "        for p in self.primes:\n",
    "            if m % p == 0:\n",
    "                ans.append([p, 0])\n",
    "                while m % p == 0:\n",
    "                    ans[-1][1] += 1\n",
    "                    m //= p\n",
    "                if m == 1:\n",
    "                    return ans\n",
    "\n",
    "        assert self.is_prime(m), '%d存在不只一个大于n的素因子，无法进一步分解' % m\n",
    "        ans.append([m, 1])\n",
    "        return ans\n",
    "    \n",
    "p = Primer()\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, a: List[int]) -> int:\n",
    "        mp = defaultdict(int)\n",
    "        for i, v in enumerate(a):\n",
    "            lt = []\n",
    "            for u, k in p.decompose(i + 1):\n",
    "                if k % 2 == 1:\n",
    "                    lt.append(u)\n",
    "            mp[tuple(lt)] += v\n",
    "        return max(mp.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "a = [i**2 for i in range(1,10001)]\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        L = [0] * 10**5\n",
    "        n = len(nums)\n",
    "        for i in range(1,n+1):\n",
    "            for j in a:\n",
    "                if j*i >= n+1:break\n",
    "                L[i] += nums[j*i-1]\n",
    "        return max(L)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "@cache\n",
    "def core(n: int) -> int:\n",
    "    res = 1\n",
    "    for i in range(2, isqrt(n) + 1):\n",
    "        if n == 1:\n",
    "            break\n",
    "        e = 0\n",
    "        while n % i == 0:\n",
    "            e += 1\n",
    "            n //= i\n",
    "        print(e, n)\n",
    "        # e = n // i\n",
    "        # n -= e * i\n",
    "        if e % 2:\n",
    "            res *= i\n",
    "    if n > 1:\n",
    "        res *= n\n",
    "    return res\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        ans = 0\n",
    "        n = len(nums)\n",
    "        s = [0] * (n + 1)\n",
    "        for i, x in enumerate(nums):\n",
    "            s[core(i + 1)] += x\n",
    "        print(s)\n",
    "        print(core(3), core(6), core(16))\n",
    "        return max(s)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]\n",
    "\n",
    "@cache\n",
    "def core(x):\n",
    "    if x == 1: return 1\n",
    "    for p in primes:\n",
    "        if x%p == 0:\n",
    "            res = core(x//p)\n",
    "            return res//p if res%p==0 else res*p\n",
    "    return x\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        score = Counter()\n",
    "        for i,n in enumerate(nums): score[core(i+1)] += n\n",
    "        return max(score.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        \n",
    "        def prime_factor(num: int) -> List[int]:\n",
    "            ans = Counter()\n",
    "            up = int(num ** 0.5 + 1)\n",
    "            for i in range(2, up):\n",
    "                while num % i == 0:\n",
    "                    num //= i\n",
    "                    ans[i] += 1\n",
    "            if num != 1:\n",
    "                ans[num] += 1\n",
    "            return ans\n",
    "        \n",
    "        ans = 0\n",
    "        cnts = collections.defaultdict(lambda:[])\n",
    "        \n",
    "        for idx, num in enumerate(nums):\n",
    "            keys = []\n",
    "            for k, v in prime_factor(idx + 1).items():\n",
    "                if v % 2 == 1:\n",
    "                    keys.append(k)\n",
    "            cnts[tuple(sorted(keys))].append(num)\n",
    "            if not keys:\n",
    "                ans += num\n",
    "                \n",
    "        ans = max(ans, max(nums))\n",
    "                \n",
    "        for _, arr in cnts.items():\n",
    "            ans = max(ans, sum(arr))\n",
    "        \n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class PrimeTable:\n",
    "    def __init__(self, n=int((10**9)**0.5)+3) -> None:\n",
    "        #值域1e9的话考虑质因子，只需小于等于(10**9)**0.5的质数即可\n",
    "        #任意一个正整数n最多只有一个质因子大于根号n\n",
    "        self.n = n\n",
    "        self.primes = [] #小于等于n的所有质数\n",
    "        self.min_div = [0] * (n+1)\n",
    "        self.min_div[1] = 1\n",
    " \n",
    "        mu = [0] * (n+1)\n",
    "        phi = [0] * (n+1)\n",
    "        mu[1] = 1\n",
    "        phi[1] = 1\n",
    " \n",
    "        for i in range(2, n+1):\n",
    "            if not self.min_div[i]:\n",
    "                self.primes.append(i)\n",
    "                self.min_div[i] = i\n",
    "                mu[i] = -1\n",
    "                phi[i] = i-1\n",
    "            for p in self.primes:\n",
    "                if i * p > n: break\n",
    "                self.min_div[i*p] = p\n",
    "                if i % p == 0:\n",
    "                    phi[i*p] = phi[i] * p\n",
    "                    break\n",
    "                else:\n",
    "                    mu[i*p] = -mu[i]\n",
    "                    phi[i*p] = phi[i] * (p - 1)\n",
    "    # x是否质数\n",
    "    def is_prime(self, x:int):\n",
    "        if x < 2: return False\n",
    "        if x <= self.n: return self.min_div[x] == x\n",
    "        for p in self.primes:\n",
    "            if p * p > x: break\n",
    "            if x % i == 0: return False\n",
    "        return True\n",
    "\n",
    "    # x分解质因数:[p, cnt] 质因子p，个数cnt\n",
    "    # 用的yield，当作一个可遍历的数据对象\n",
    "    #一个数一定可以分解为多个质数的连乘积\n",
    "    #n = x^a * y^b * z^c ...  （x,y,z为质因数） n的约数个数=(a+1)(b+1)...(y+1)\n",
    "\n",
    "    def prime_factorization(self, x:int):\n",
    "        for p in self.primes:\n",
    "            if p * p > x: break\n",
    "            if x <= self.n: break\n",
    "            if x % p == 0:\n",
    "                cnt = 0\n",
    "                while x % p == 0: cnt += 1; x //= p\n",
    "                yield p, cnt\n",
    "        while (1 < x and x <= self.n):\n",
    "            p, cnt = self.min_div[x], 0\n",
    "            while x % p == 0: cnt += 1; x //= p\n",
    "            yield p, cnt\n",
    "        if x >= self.n and x > 1:\n",
    "            #小于等于(10**9)**0.5的质数除干净了，如果还大于1\n",
    "            # 那么余下的数一定是一个大于等于n的质数\n",
    "            yield x, 1\n",
    "            \n",
    "    # x的所有因数\n",
    "    def get_factors(self, x:int):\n",
    "        factors = [1]\n",
    "        for p, b in self.prime_factorization(x):\n",
    "            n = len(factors)\n",
    "            for j in range(1, b+1):\n",
    "                for d in factors[:n]:\n",
    "                    factors.append(d * (p ** j))\n",
    "        return factors\n",
    "\n",
    "pt=PrimeTable()\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        n=len(nums)\n",
    "        nums=[0]+nums\n",
    "        d=defaultdict(int)\n",
    "        for i,x in enumerate(nums):\n",
    "            if i<1:\n",
    "                continue\n",
    "            t=1\n",
    "            for p,c in pt.prime_factorization(i):\n",
    "                if c%2==1:\n",
    "                    t*=p\n",
    "            d[t]+=x\n",
    "        #print(d)\n",
    "        return max(d.values())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# 预处理\n",
    "def getCore(num):\n",
    "    d = 2\n",
    "    res = 1\n",
    "    while d < num:\n",
    "        cnt = 0\n",
    "        while num % d == 0:\n",
    "            num //= d\n",
    "            cnt += 1\n",
    "        if cnt&1:\n",
    "            res *= d\n",
    "        d += 1\n",
    "    # if num > 1:\n",
    "    res *= num\n",
    "    return res\n",
    "\n",
    "maxValue = int(1e4)\n",
    "        \n",
    "# 获取同一组对应的所有下标值\n",
    "group = defaultdict(list)\n",
    "for num in range(1,maxValue+1):    \n",
    "    group[getCore(num)].append(num)\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        res = 0\n",
    "\n",
    "        # 遍历每个下标分组\n",
    "        for varr in group.values():\n",
    "            # 分组求和\n",
    "            t = 0\n",
    "            for i in varr:\n",
    "                if i > n:\n",
    "                    break\n",
    "                t += nums[i-1]\n",
    "            res = max(res,t)\n",
    "        \n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "# auther yeling\n",
    "from typing import List\n",
    "from bisect import *\n",
    "from collections import *\n",
    "from functools import *\n",
    "from itertools import *\n",
    "from math import *\n",
    "from queue import PriorityQueue\n",
    "from typing import Optional\n",
    "from heapq import *\n",
    "import string\n",
    "# from sortedcontainers import SortedList\n",
    "\n",
    "\n",
    "INF = 2 ** 64 - 1\n",
    "MOD = 10 ** 9 + 7\n",
    "\n",
    "class Solution:\n",
    "    # 495 / 663 \n",
    "    # 556 / 663 \n",
    "    def maximumSum(self, nums: List[int]) -> int:    \n",
    "        n = len(nums)\n",
    "        # 一个数字处以 4 9 25 。。。 剩下来的值，\n",
    "        # 如果两个数字剩下来的相同，他们的乘积就是完全平方数\n",
    "        core = defaultdict(list)\n",
    "        for i in range(n):\n",
    "            curr = i + 1\n",
    "            for j in range(2, int(sqrt(n)) + 1):\n",
    "                if curr < j:\n",
    "                    break\n",
    "                while curr % (j * j) == 0:\n",
    "                    curr //= (j * j)\n",
    "            core[curr].append(i)\n",
    "        # print(core)\n",
    "        ans = 0\n",
    "        for k in core:\n",
    "            temp = sum(nums[v] for v in core[k])\n",
    "            ans = max(ans, temp)\n",
    "\n",
    "\n",
    "        return ans\n",
    "   "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from typing import List\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        \"\"\"\n",
    "\n",
    "        :param nums:\n",
    "        :return:\n",
    "        \"\"\"\n",
    "        len1 = len(nums)\n",
    "        ret = []\n",
    "        for i in range(1, 10000):\n",
    "            cnt = 1\n",
    "            ret2 = []\n",
    "            gap = i\n",
    "            while gap * cnt ** 2 <= len1:\n",
    "                ret2.append(cnt ** 2 * gap)\n",
    "                cnt += 1\n",
    "            if len(ret2) == 0:\n",
    "                break\n",
    "            ret.append(ret2)\n",
    "        s1 = max(nums)\n",
    "        for i in ret:\n",
    "            v1 = 0\n",
    "            for x in i:\n",
    "                v1 += nums[x - 1]\n",
    "            s1 = max(s1, v1)\n",
    "        return s1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "maxValue = int(1e4)\n",
    "        \n",
    "# 获取[1, maxValue]内所有质数\n",
    "tmp = [1] * (maxValue + 1)        \n",
    "prime = []\n",
    "\n",
    "for i in range(2,maxValue + 1):\n",
    "    if tmp[i] == 1:\n",
    "        prime.append(i)\n",
    "\n",
    "    for j in prime:\n",
    "        if j*i > maxValue:\n",
    "            break\n",
    "\n",
    "        tmp[i*j] = 0\n",
    "\n",
    "        if i % j == 0:\n",
    "            break\n",
    "\n",
    "# 根据core分组\n",
    "group = defaultdict(list)\n",
    "# 质因数分解\n",
    "for num in range(1,maxValue+1):    \n",
    "    cur = num\n",
    "    tmp = 1\n",
    "    for p in prime:\n",
    "        cnt = 0\n",
    "        while num % p == 0:\n",
    "            cnt += 1\n",
    "            num //= p\n",
    "        if cnt&1:\n",
    "            tmp *= p\n",
    "        if num < p:\n",
    "            break\n",
    "    \n",
    "    group[tmp].append(cur)\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        res = 0\n",
    "\n",
    "        # 遍历每个下标分组\n",
    "        for varr in group.values():\n",
    "            # 分组求和\n",
    "            t = 0\n",
    "            for i in varr:\n",
    "                if i > n:\n",
    "                    break\n",
    "                t += nums[i-1]\n",
    "            res = max(res,t)\n",
    "        \n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Primer(object):\n",
    "    \"\"\"素数相关运算的辅助类\n",
    "\n",
    "    Attributes:\n",
    "        1. n：用素数筛选法提前计算好的最大数\n",
    "        2. primes：n以内的所有素数列表\n",
    "        3. min_prime_factors：每个下标数的最小素因数（最小素因数不存在时为-1）\n",
    "\n",
    "    \"\"\"\n",
    "\n",
    "    @property\n",
    "    def n(self):\n",
    "        return self._n\n",
    "\n",
    "    @property\n",
    "    def primes(self):\n",
    "        return self._primes\n",
    "\n",
    "    @property\n",
    "    def min_prime_factors(self):\n",
    "        return self._min_prime_factors\n",
    "\n",
    "    def __init__(self, n=31625):\n",
    "        \"\"\"初始化\n",
    "\n",
    "        生成n以内的所有素数primes，同时得到每个数的最小素因数min_prime_factors\n",
    "\n",
    "        Time Complexity:\n",
    "            O(n)\n",
    "\n",
    "        \"\"\"\n",
    "        primes = []\n",
    "        min_prime_factors = [-1, -1] + [0] * (n - 1)\n",
    "        for i in range(2, n + 1):\n",
    "            if min_prime_factors[i] == 0:\n",
    "                primes.append(i)\n",
    "                min_prime_factors[i] = i\n",
    "            j = 0\n",
    "            while i * primes[j] <= n:\n",
    "                min_prime_factors[i * primes[j]] = primes[j]\n",
    "                if i % primes[j] == 0:\n",
    "                    break\n",
    "                j += 1\n",
    "        self._n = n\n",
    "        self._primes = primes\n",
    "        self._min_prime_factors = min_prime_factors\n",
    "\n",
    "    def _miller_rabin(self, m, seed):\n",
    "        assert m > 2 and (m & 1) == 1, '参数m不能设为%d' % m\n",
    "\n",
    "        k = 0\n",
    "        t = m - 1\n",
    "        while (t & 1) == 1:\n",
    "            t >>= 1\n",
    "            k += 1\n",
    "\n",
    "        a = pow(seed, t, m)\n",
    "        if a == 1 or a == m - 1:\n",
    "            return True\n",
    "        for i in range(k - 1):\n",
    "            a = pow(a, 2, m)\n",
    "            if a == 1:\n",
    "                return False\n",
    "            if a == m - 1:\n",
    "                return True\n",
    "        return False\n",
    "\n",
    "    def is_prime(self, m, k=10):\n",
    "        \"\"\"\n",
    "\n",
    "        Returns:\n",
    "            m是否为素数\n",
    "\n",
    "        Procedure:\n",
    "            1. 若m <= n，使用min_prime_factors直接判定，O(1)\n",
    "            2. 若m <= n * n或m存在n以内的素因子，遍历primes判定，O(len(primes))\n",
    "            3. 若m > n * n且m不存在n以内的素因子，miller_rabin随机算法判定，合数判成素数的错误率小于4^(-k)，O(len(primes) + k*log(n))\n",
    "\n",
    "        \"\"\"\n",
    "        if m <= self.n:\n",
    "            return self.min_prime_factors[m] == m\n",
    "        for p in self.primes:\n",
    "            if m % p == 0:\n",
    "                return False\n",
    "            if p * p > m:\n",
    "                return True\n",
    "        return all((self._miller_rabin(m, i) for i in self.primes[:k]))\n",
    "\n",
    "    def decompose(self, m):\n",
    "        \"\"\"正整数质因子分解\n",
    "\n",
    "        Returns:\n",
    "            [[p1, a1], [p2, a2] ...]，代表m = (p1 ^ a1) * (P2 ^ a2) * ...\n",
    "            举例：输入40，返回[[2, 3], [5, 1]]\n",
    "\n",
    "        Attention:\n",
    "            若m存在不只一个大于n的素因子，将命中断言，无法进一步分解\n",
    "\n",
    "        Time Complexity:\n",
    "            O(len(primes))\n",
    "\n",
    "        \"\"\"\n",
    "        assert m > 0, '参数m不能设为%d' % m\n",
    "\n",
    "        if m == 1:\n",
    "            return []\n",
    "        if m <= self.n:\n",
    "            t = self.min_prime_factors[m]\n",
    "            ans = self.decompose(m // t)\n",
    "            if ans and ans[-1][0] == t:\n",
    "                ans[-1][1] += 1\n",
    "            else:\n",
    "                ans.append([t, 1])\n",
    "            return ans\n",
    "        ans = []\n",
    "        for p in self.primes:\n",
    "            if m % p == 0:\n",
    "                ans.append([p, 0])\n",
    "                while m % p == 0:\n",
    "                    ans[-1][1] += 1\n",
    "                    m //= p\n",
    "                if m == 1:\n",
    "                    return ans\n",
    "\n",
    "        assert self.is_prime(m), '%d存在不只一个大于n的素因子，无法进一步分解' % m\n",
    "        ans.append([m, 1])\n",
    "        return ans\n",
    "    \n",
    "p = Primer()\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, a: List[int]) -> int:\n",
    "        mp = defaultdict(int)\n",
    "        for i, v in enumerate(a):\n",
    "            lt = []\n",
    "            for u, k in p.decompose(i + 1):\n",
    "                if k % 2 == 1:\n",
    "                    lt.append(u)\n",
    "            mp[tuple(lt)] += v\n",
    "        return max(mp.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        \n",
    "        n=len(nums)\n",
    "        cnt=defaultdict(list)\n",
    "        for i in range(1,n+1):\n",
    "            if int(i**0.5)**2==i:\n",
    "                cnt[(1)].append(i)\n",
    "                continue\n",
    "            \n",
    "            arr=[]\n",
    "            cur=i\n",
    "            for j in range(2,int(i**0.5)+1):\n",
    "                flag=0\n",
    "                while i%j==0:\n",
    "                    i//=j\n",
    "                    flag^=1\n",
    "                if flag:\n",
    "                    arr.append(j)\n",
    "            if i>1:arr.append(i)\n",
    "            # print(cur,arr)\n",
    "            cnt[tuple(arr)].append(cur)\n",
    "        \n",
    "        # print(cnt)\n",
    "        res=0\n",
    "        \n",
    "        for k,v in cnt.items():\n",
    "            s=sum(nums[i-1] for i in v)\n",
    "            res=max(res,s)\n",
    "        \n",
    "        return res\n",
    "            \n",
    "                    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from typing import List\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        \"\"\"\n",
    "\n",
    "        :param nums:\n",
    "        :return:\n",
    "        \"\"\"\n",
    "        len1 = len(nums)\n",
    "        ret = []\n",
    "        for i in range(1, 1000000):\n",
    "            cnt = 1\n",
    "            ret2 = []\n",
    "            gap = i\n",
    "            while gap * cnt ** 2 <= len1:\n",
    "                ret2.append(cnt ** 2 * gap)\n",
    "                cnt += 1\n",
    "            if len(ret2) == 0:\n",
    "                break\n",
    "            ret.append(ret2)\n",
    "        s1 = max(nums)\n",
    "        for i in ret:\n",
    "            v1 = 0\n",
    "            for x in i:\n",
    "                v1 += nums[x - 1]\n",
    "            s1 = max(s1, v1)\n",
    "        return s1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        ans = 0\n",
    "        n = len(nums)\n",
    "        sqr = [i*i for i in range(1, 40000)]\n",
    "        for i in range(1, n+1):\n",
    "            tmp = 0\n",
    "            for x in sqr:\n",
    "                if x*i <= n:\n",
    "                    tmp += nums[i*x-1]\n",
    "                else:\n",
    "                    break\n",
    "            # print(i, tmp)\n",
    "            ans = max(ans, tmp)\n",
    "        \n",
    "        return ans\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from math import *\n",
    "from queue import PriorityQueue,Queue\n",
    "from typing import *\n",
    "from heapq import *\n",
    "from functools import lru_cache,cache\n",
    "from string import *\n",
    "from itertools import product\n",
    "from collections import defaultdict\n",
    "# by hangpengjie\n",
    "class Solution:\n",
    "    # T4\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        dp = [0]+nums.copy()\n",
    "        d = [i*i for i in range(2,n+10)]\n",
    "        @cache\n",
    "        def core(p :int)->int:\n",
    "            t = 0\n",
    "            while p >= d[t]:\n",
    "                while p % d[t] == 0:\n",
    "                    p //= d[t]\n",
    "                t += 1\n",
    "            return p\n",
    "        s = Counter()\n",
    "        for i,x in enumerate(nums,1):\n",
    "            s[core(i)] += x\n",
    "        return max(s.values())\n",
    "        \n",
    "    \n",
    "    \n",
    "    \n",
    "\n",
    "\n",
    "s = Solution()\n",
    "s.maximumSum([5,10,3,10,1,13,7,9,4])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        nums = [0]+nums\n",
    "        idx =[]\n",
    "        p = []\n",
    "        for i in range(1,n+1):\n",
    "            if i*i<=n:p.append(i*i)\n",
    "        for i in range(1,n+1):\n",
    "            tmp = []\n",
    "            for a in p:\n",
    "                if a*i<=n:tmp.append(a*i)\n",
    "            if  tmp : idx.append(tmp)\n",
    "        mx = 0\n",
    "        for v in idx:\n",
    "            a = [nums[i] for i in v]\n",
    "            mx = max(mx,sum(a))\n",
    "        return mx\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        def prime_factor(x):\n",
    "            prime = True\n",
    "            for i in range(2, int(x**0.5) + 1):\n",
    "                if not x % i:\n",
    "                    res = prime_factor(x // i)\n",
    "                    res.append(i)\n",
    "                    prime = False\n",
    "                    break\n",
    "            if prime:\n",
    "                return [x]\n",
    "            return res\n",
    "        \n",
    "        n = len(nums)\n",
    "        arr = []\n",
    "        table = collections.defaultdict(list)\n",
    "        table[()].append(0)\n",
    "        for i in range(1, n):\n",
    "            tmp = prime_factor(i + 1)\n",
    "            distinct = []\n",
    "            j = 0\n",
    "            if len(tmp) > 1:\n",
    "                while j < len(tmp) - 1:\n",
    "                    if tmp[j] != tmp[j + 1]:\n",
    "                        distinct.append(tmp[j])\n",
    "                        j += 1\n",
    "                    else:\n",
    "                        j += 2\n",
    "                if j == len(tmp) - 1:\n",
    "                    distinct.append(tmp[j])\n",
    "            else:\n",
    "                distinct = tmp\n",
    "            # print(tmp, distinct)\n",
    "            table[tuple(distinct)].append(i)\n",
    "        # print(table)\n",
    "        ans = 0\n",
    "        for each in nums:\n",
    "            ans = max(ans, each)\n",
    "        for k, v in table.items():\n",
    "            if len(v) == 1: continue\n",
    "            tmp = 0\n",
    "            for i in v:\n",
    "                tmp += nums[i]\n",
    "            ans = max(ans, tmp)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class PrimeTable:\n",
    "    def __init__(self, n=int((10**9)**0.5)+3) -> None:\n",
    "        #值域1e9的话考虑质因子，只需小于等于(10**9)**0.5的质数即可\n",
    "        #任意一个正整数n最多只有一个质因子大于根号n\n",
    "        self.n = n\n",
    "        self.primes = [] #小于等于n的所有质数\n",
    "        self.min_div = [0] * (n+1)\n",
    "        self.min_div[1] = 1\n",
    " \n",
    "        mu = [0] * (n+1)\n",
    "        phi = [0] * (n+1)\n",
    "        mu[1] = 1\n",
    "        phi[1] = 1\n",
    " \n",
    "        for i in range(2, n+1):\n",
    "            if not self.min_div[i]:\n",
    "                self.primes.append(i)\n",
    "                self.min_div[i] = i\n",
    "                mu[i] = -1\n",
    "                phi[i] = i-1\n",
    "            for p in self.primes:\n",
    "                if i * p > n: break\n",
    "                self.min_div[i*p] = p\n",
    "                if i % p == 0:\n",
    "                    phi[i*p] = phi[i] * p\n",
    "                    break\n",
    "                else:\n",
    "                    mu[i*p] = -mu[i]\n",
    "                    phi[i*p] = phi[i] * (p - 1)\n",
    "    # x是否质数\n",
    "    def is_prime(self, x:int):\n",
    "        if x < 2: return False\n",
    "        if x <= self.n: return self.min_div[x] == x\n",
    "        for p in self.primes:\n",
    "            if p * p > x: break\n",
    "            if x % i == 0: return False\n",
    "        return True\n",
    "\n",
    "    # x分解质因数:[p, cnt] 质因子p，个数cnt\n",
    "    # 用的yield，当作一个可遍历的数据对象\n",
    "    #一个数一定可以分解为多个质数的连乘积\n",
    "    #n = x^a * y^b * z^c ...  （x,y,z为质因数） n的约数个数=(a+1)(b+1)...(y+1)\n",
    "\n",
    "    def prime_factorization(self, x:int):\n",
    "        for p in self.primes:\n",
    "            if p * p > x: break\n",
    "            if x <= self.n: break\n",
    "            if x % p == 0:\n",
    "                cnt = 0\n",
    "                while x % p == 0: cnt += 1; x //= p\n",
    "                yield p, cnt\n",
    "        while (1 < x and x <= self.n):\n",
    "            p, cnt = self.min_div[x], 0\n",
    "            while x % p == 0: cnt += 1; x //= p\n",
    "            yield p, cnt\n",
    "        if x >= self.n and x > 1:\n",
    "            #小于等于(10**9)**0.5的质数除干净了，如果还大于1\n",
    "            # 那么余下的数一定是一个大于等于n的质数\n",
    "            yield x, 1\n",
    "            \n",
    "    # x的所有因数\n",
    "    def get_factors(self, x:int):\n",
    "        factors = [1]\n",
    "        for p, b in self.prime_factorization(x):\n",
    "            n = len(factors)\n",
    "            for j in range(1, b+1):\n",
    "                for d in factors[:n]:\n",
    "                    factors.append(d * (p ** j))\n",
    "        return factors\n",
    "\n",
    "pt=PrimeTable()\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        n=len(nums)\n",
    "        nums=[0]+nums\n",
    "        d=defaultdict(int)\n",
    "        for i,x in enumerate(nums):\n",
    "            if i<1:\n",
    "                continue\n",
    "            t=[]\n",
    "            for p,c in pt.prime_factorization(i):\n",
    "                if c%2==1:\n",
    "                    t.append(p)\n",
    "            d[tuple(t)]+=x\n",
    "        #print(d)\n",
    "        return max(d.values())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# 预处理\n",
    "def getCore(num):\n",
    "    d = 2\n",
    "    res = 1\n",
    "    while d < num:\n",
    "        cnt = 0\n",
    "        while num % d == 0:\n",
    "            num //= d\n",
    "            cnt += 1\n",
    "        if cnt&1:\n",
    "            res *= d\n",
    "        d += 1\n",
    "    # if num > 1:\n",
    "    res *= num\n",
    "    return res\n",
    "\n",
    "maxValue = int(1e4)\n",
    "        \n",
    "# 获取同一组对应的所有下标值\n",
    "group = defaultdict(list)\n",
    "for num in range(1,maxValue+1):    \n",
    "    group[getCore(num)].append(num)\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        res = 0\n",
    "\n",
    "        # 遍历每个下标分组\n",
    "        for varr in group.values():\n",
    "            # 分组求和\n",
    "            t = 0\n",
    "            for i in varr:\n",
    "                if i > n:\n",
    "                    break\n",
    "                t += nums[i-1]\n",
    "            res = max(res,t)\n",
    "        \n",
    "        return res# 预处理\n",
    "maxValue = int(1e4)\n",
    "        \n",
    "# 获取[1, maxValue]内所有质数\n",
    "tmp = [1] * (maxValue + 1)        \n",
    "prime = []\n",
    "\n",
    "for i in range(2,maxValue + 1):\n",
    "    if tmp[i] == 1:\n",
    "        prime.append(i)\n",
    "\n",
    "    for j in prime:\n",
    "        if j*i > maxValue:\n",
    "            break\n",
    "\n",
    "        tmp[i*j] = 0\n",
    "\n",
    "        if i % j == 0:\n",
    "            break\n",
    "\n",
    "# 根据core分组\n",
    "group = defaultdict(list)\n",
    "# 质因数分解\n",
    "for num in range(1,maxValue+1):    \n",
    "    cur = num\n",
    "    tmp = 1\n",
    "    for p in prime:\n",
    "        cnt = 0\n",
    "        while num % p == 0:\n",
    "            cnt += 1\n",
    "            num //= p\n",
    "        if cnt&1:\n",
    "            tmp *= p\n",
    "        if num < p:\n",
    "            break\n",
    "    \n",
    "    group[tmp].append(cur)\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        res = 0\n",
    "\n",
    "        # 遍历每个下标分组\n",
    "        for varr in group.values():\n",
    "            # 分组求和\n",
    "            t = 0\n",
    "            for i in varr:\n",
    "                if i > n:\n",
    "                    break\n",
    "                t += nums[i-1]\n",
    "            res = max(res,t)\n",
    "        \n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        n=len(nums)\n",
    "        cubes=[]\n",
    "        d=defaultdict(list)\n",
    "        for i in range(1,n+1):\n",
    "            x=int(sqrt(i))\n",
    "            if x*x==i:\n",
    "                cubes.append(i)\n",
    "            else:\n",
    "                d[i].append(i)\n",
    "        ans=sum([nums[x-1] for x in cubes])\n",
    "        s=set(cubes)\n",
    "        for i in range(2,n+1):\n",
    "            if i in s:\n",
    "                continue\n",
    "            for c in cubes[1:]:\n",
    "                x=c*i\n",
    "                if x<=n:\n",
    "                    d[i].append(c*i)\n",
    "            ans=max(ans,sum([nums[x-1] for x in d[i]]))\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        prim_result = self.pick_prim(n + 1)\n",
    "        result = 0\n",
    "        memory = {}\n",
    "        for i in range(1, n + 1):\n",
    "            if self.is_perfect_sqrt(i):\n",
    "                result += nums[i - 1]\n",
    "                continue\n",
    "            prim_str = self.find_sub(i, prim_result)\n",
    "            if prim_str not in memory:\n",
    "                memory[prim_str] = [i - 1]\n",
    "            else:\n",
    "                memory[prim_str].append(i - 1)\n",
    "        for list_value in memory.values():\n",
    "            sum = 0\n",
    "            for index in list_value:\n",
    "                sum += nums[index]\n",
    "            result = max(result, sum)\n",
    "        return result\n",
    "\n",
    "\n",
    "    def pick_prim(self,n):\n",
    "        result = []\n",
    "        is_prime = [True] * (n + 1)\n",
    "        is_prime[0] = is_prime[1] = False\n",
    "        for i in range(2, n + 1):\n",
    "            if is_prime[i]:\n",
    "                if i * i <= n:\n",
    "                    j = i * i\n",
    "                    while j <= n:\n",
    "                        is_prime[j] = False\n",
    "                        j = j + i\n",
    "        for i in range(len(is_prime)):\n",
    "            if is_prime[i]:\n",
    "                result.append(i)\n",
    "        return result\n",
    "\n",
    "\n",
    "    def is_perfect_sqrt(self, value):\n",
    "        sqrt = math.sqrt(value)\n",
    "        return sqrt.is_integer()\n",
    "\n",
    "\n",
    "    def find_sub(self, value, prim):\n",
    "        result = []\n",
    "        final = []\n",
    "        i = 0\n",
    "        while i < len(prim) and value >= prim[i]:\n",
    "            if value % prim[i] == 0:\n",
    "                result.append(prim[i])\n",
    "                value //= prim[i]\n",
    "            else:\n",
    "                i += 1\n",
    "        result = [-1] + result\n",
    "        i = 1\n",
    "        count = 0\n",
    "        while i < len(result):\n",
    "            if result[i] != result[i - 1]:\n",
    "                if count % 2 == 1:\n",
    "                    final.append(str(result[i - 1]))\n",
    "                count = 1\n",
    "            else:\n",
    "                count += 1\n",
    "            if i == len(result) - 1 and count % 2 == 1:\n",
    "                final.append(str(result[-1]))\n",
    "            i += 1\n",
    "        result = '+'.join(final)\n",
    "        return result\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "\n",
    "        n = len(nums)\n",
    "        def getf(v):\n",
    "            m = 2\n",
    "            r = 1\n",
    "            while m * m <= v:\n",
    "                if v % m == 0:\n",
    "                    c = 0\n",
    "                    while v % m == 0:\n",
    "                        v //= m\n",
    "                        c += 1\n",
    "                    if c % 2 == 1: r *= m\n",
    "                m += 1\n",
    "            r *= v\n",
    "            return r        \n",
    "        \n",
    "        c = defaultdict(list)\n",
    "        for i in range(1, n+1): c[getf(i)].append(i-1)\n",
    "        ans = 0\n",
    "        for k in c:\n",
    "            s = 0\n",
    "            for i in c[k]:\n",
    "                s += nums[i]\n",
    "            ans = max(ans, s)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        d = defaultdict(set)\n",
    "        l = len(nums)\n",
    "        for n in range(1,l+1):\n",
    "            m = n \n",
    "            i = 2\n",
    "            while i * i <= n:\n",
    "                if n % (i * i) == 0:\n",
    "                    n //= i * i \n",
    "                else:\n",
    "                    i += 1\n",
    "            d[n].add(m)\n",
    "        ans = 0\n",
    "        for s in d.values():\n",
    "            if len(s) > 0:\n",
    "                ans = max(ans,sum(nums[i-1] for i in s))\n",
    "        return ans \n",
    "        \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "def fj(N):\n",
    "    ret=0\n",
    "    i=2\n",
    "    while i*i <=N:\n",
    "        if N%i==0:\n",
    "            while N%i==0:\n",
    "                N//=i\n",
    "                ret^=(1<<i)\n",
    "        i+=1\n",
    "    if N!=1:\n",
    "        ret^=(1<<N)\n",
    "    return ret\n",
    "tt=[0,0]+[fj(i) for i in range(2,int(1e4+10))]\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        d=defaultdict(int)\n",
    "        ret=nums[0]\n",
    "        for i,v in enumerate(nums):\n",
    "            if i==0: continue\n",
    "            x=tt[i+1]\n",
    "            d[x]+=v\n",
    "            if int(math.sqrt(i+1))**2==(i+1):\n",
    "                ret=max(ret,d[x]+nums[0])\n",
    "            else:\n",
    "                ret=max(ret,d[x])\n",
    "        return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    p = []\n",
    "    st = [True for i in range(int(1e5 + 1))]\n",
    "\n",
    "    def getPrimes(self, n):\n",
    "        self.st[1] = False\n",
    "        for i in range(2, n + 1):\n",
    "            if self.st[i]:\n",
    "                self.p.append(i)\n",
    "            for j, prime in enumerate(self.p):\n",
    "                if i * prime > n:\n",
    "                    break\n",
    "                self.st[i * prime] = False\n",
    "                if i % prime == 0:\n",
    "                    break\n",
    "    \n",
    "    def getFactors(self, x):\n",
    "        r = int(sqrt(x))\n",
    "        f = []\n",
    "        for i in range(2, r + 1):\n",
    "            if x % i == 0:\n",
    "                cnt = 0\n",
    "                while x % i == 0:\n",
    "                    cnt += 1\n",
    "                    x /= i\n",
    "                if cnt % 2 != 0:\n",
    "                    f.append(i)\n",
    "        if x > 1:\n",
    "            f.append(x)\n",
    "        return tuple(f)\n",
    "\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        # 完全平方数和非完全平方数相乘肯定不是完全平方数，所以要么全选完全平方数，要么全选非完全平方数\n",
    "        # 所有的完全平方数下标都选上是一个候选答案\n",
    "        # 剩下的数只统计出现奇数次的素因子\n",
    "        # 两个数可以放在一起，当且仅当这两个数出现奇数次的素因子的种类完全一样\n",
    "        # 统计答案即可\n",
    "        if len(self.p) == 0:\n",
    "            self.getPrimes(int(1e5))\n",
    "        \n",
    "        res = 0\n",
    "        n = len(nums)\n",
    "        for i in range(1, n + 1):\n",
    "            if i * i <= n:\n",
    "                res += nums[i * i - 1]\n",
    "        \n",
    "        ans2 = {}\n",
    "        for i in range(n):\n",
    "            j = i + 1\n",
    "            r = int(sqrt(j))\n",
    "            if r * r != j:\n",
    "                factors = self.getFactors(j)\n",
    "                if ans2.get(factors) != None:\n",
    "                    ans2[factors] += nums[i]\n",
    "                else:\n",
    "                    ans2[factors] = nums[i]\n",
    "        for key in ans2.keys():\n",
    "            res = max(res, ans2[key])\n",
    "\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        prim_result = self.pick_prim(n + 1)\n",
    "        result = 0\n",
    "        memory = {}\n",
    "        for i in range(1, n + 1):\n",
    "            if self.is_perfect_sqrt(i):\n",
    "                result += nums[i - 1]\n",
    "                continue\n",
    "            prim_str = self.find_sub(i, prim_result)\n",
    "            if prim_str not in memory:\n",
    "                memory[prim_str] = [i - 1]\n",
    "            else:\n",
    "                memory[prim_str].append(i - 1)\n",
    "        for list_value in memory.values():\n",
    "            sum = 0\n",
    "            for index in list_value:\n",
    "                sum += nums[index]\n",
    "            result = max(result, sum)\n",
    "        return result\n",
    "\n",
    "\n",
    "    def pick_prim(self,n):\n",
    "        result = []\n",
    "        is_prime = [True] * (n + 1)\n",
    "        is_prime[0] = is_prime[1] = False\n",
    "        for i in range(2, n + 1):\n",
    "            if is_prime[i]:\n",
    "                if i * i <= n:\n",
    "                    j = i * i\n",
    "                    while j <= n:\n",
    "                        is_prime[j] = False\n",
    "                        j = j + i\n",
    "        for i in range(len(is_prime)):\n",
    "            if is_prime[i]:\n",
    "                result.append(i)\n",
    "        return result\n",
    "\n",
    "\n",
    "    def is_perfect_sqrt(self, value):\n",
    "        sqrt = math.sqrt(value)\n",
    "        return sqrt.is_integer()\n",
    "\n",
    "\n",
    "    def find_sub(self, value, prim):\n",
    "        result = []\n",
    "        final = []\n",
    "        i = 0\n",
    "        while i < len(prim) and value >= prim[i]:\n",
    "            if value % prim[i] == 0:\n",
    "                result.append(prim[i])\n",
    "                value //= prim[i]\n",
    "            else:\n",
    "                i += 1\n",
    "        result = [-1] + result\n",
    "        i = 1\n",
    "        count = 0\n",
    "        while i < len(result):\n",
    "            if result[i] != result[i - 1]:\n",
    "                if count % 2 == 1:\n",
    "                    final.append(str(result[i - 1]))\n",
    "                count = 1\n",
    "            else:\n",
    "                count += 1\n",
    "            if i == len(result) - 1 and count % 2 == 1:\n",
    "                final.append(str(result[-1]))\n",
    "            i += 1\n",
    "        result = '+'.join(final)\n",
    "        return result\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        prim_result = self.pick_prim(n + 1)\n",
    "        result = 0\n",
    "        memory = {}\n",
    "        for i in range(1, n + 1):\n",
    "            if self.is_perfect_sqrt(i):\n",
    "                result += nums[i - 1]\n",
    "                continue\n",
    "            prim_str = self.find_sub(i, prim_result)\n",
    "            if prim_str not in memory:\n",
    "                memory[prim_str] = [i - 1]\n",
    "            else:\n",
    "                memory[prim_str].append(i - 1)\n",
    "        for list_value in memory.values():\n",
    "            sum = 0\n",
    "            for index in list_value:\n",
    "                sum += nums[index]\n",
    "            result = max(result, sum)\n",
    "        return result\n",
    "\n",
    "\n",
    "    def pick_prim(self,n):\n",
    "        result = []\n",
    "        is_prime = [True] * (n + 1)\n",
    "        is_prime[0] = is_prime[1] = False\n",
    "        for i in range(2, n + 1):\n",
    "            if is_prime[i]:\n",
    "                if i * i <= n:\n",
    "                    j = i * i\n",
    "                    while j <= n:\n",
    "                        is_prime[j] = False\n",
    "                        j = j + i\n",
    "        for i in range(len(is_prime)):\n",
    "            if is_prime[i]:\n",
    "                result.append(i)\n",
    "        return result\n",
    "\n",
    "\n",
    "    def is_perfect_sqrt(self, value):\n",
    "        sqrt = math.sqrt(value)\n",
    "        return sqrt.is_integer()\n",
    "\n",
    "\n",
    "    def find_sub(self, value, prim):\n",
    "        result = []\n",
    "        final = []\n",
    "        i = 0\n",
    "        while i < len(prim) and value >= prim[i]:\n",
    "            if value % prim[i] == 0:\n",
    "                result.append(prim[i])\n",
    "                value //= prim[i]\n",
    "            else:\n",
    "                i += 1\n",
    "        result = [-1] + result\n",
    "        i = 1\n",
    "        count = 0\n",
    "        while i < len(result):\n",
    "            if result[i] != result[i - 1]:\n",
    "                if count % 2 == 1:\n",
    "                    final.append(str(result[i - 1]))\n",
    "                count = 1\n",
    "            else:\n",
    "                count += 1\n",
    "            if i == len(result) - 1 and count % 2 == 1:\n",
    "                final.append(str(result[-1]))\n",
    "            i += 1\n",
    "        result = '+'.join(final)\n",
    "        return result\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "primes = [2]\n",
    "for i in range(3, 10001, 2):\n",
    "    if all(i % j for j in primes):\n",
    "        primes.append(i)\n",
    "\n",
    "groups = defaultdict(list)\n",
    "for i in range(1, 10001):\n",
    "    g = 0\n",
    "    ii = i\n",
    "    for j in primes:\n",
    "        k = 0\n",
    "        while ii % j == 0:\n",
    "            ii //= j\n",
    "            k += 1\n",
    "        g <<= 1\n",
    "        g |= k & 1\n",
    "    groups[g].append(i - 1)\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        return max(\n",
    "            sum(nums[i] for i in takewhile(lambda i: i < len(nums), g))\n",
    "            for g in groups.values()\n",
    "        )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        s=[]\n",
    "        \n",
    "        n=len(nums)\n",
    "        d={}\n",
    "        # lh=[1]\n",
    "        maxa=0\n",
    "        a=0\n",
    "        for j in range(1,n+1):\n",
    "            if j**2<=n:\n",
    "                a=a+nums[j**2-1]\n",
    "                s.append(j**2)\n",
    "\n",
    "        for i in range(2,n+1):\n",
    "            if i in s:\n",
    "                continue\n",
    "            d[i]=[i]\n",
    "            for j in range(2,int(sqrt((n/i)))+1):\n",
    "                if True:                                               \n",
    "                    if (i*j*j<=n):\n",
    "                        d[i].append(i*j*j)                    \n",
    "                        \n",
    "        ll=[]\n",
    "        for i in d:\n",
    "            \n",
    "            p=list(set(d[i]))\n",
    "            maxa=max(maxa,sum([nums[j-1]for j in p]))\n",
    "\n",
    "        maxa=max(maxa,a)     \n",
    "            \n",
    "        print(maxa,n,d,s,a)\n",
    "        return maxa\n",
    "               \n",
    "       "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        # res = defaultdict(list)\n",
    "        res = Counter()\n",
    "        for i in range(1, n+1):\n",
    "            demo = i\n",
    "            c = 1\n",
    "            for j in range(2, isqrt(n)+2):\n",
    "                times = 0\n",
    "                while i % j == 0:\n",
    "                    i //= j\n",
    "                    times += 1\n",
    "                if times % 2: c *= j\n",
    "            if i > 1: c *= i\n",
    "            res[demo] = c\n",
    "        ans = 0\n",
    "        print(res)\n",
    "        s = [0] * (n+1)\n",
    "        for i,x in enumerate(nums):\n",
    "            s[res[i+1]] += x\n",
    "        return max(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "cnt = [0]\n",
    "for i in range(2,10001):\n",
    "    tmp = 0\n",
    "    cur = i\n",
    "    for j in range(2,i + 1):\n",
    "        if cur == 1:\n",
    "            break\n",
    "        while cur % j == 0:\n",
    "            cur //= j\n",
    "            tmp ^= (1 << j)\n",
    "    cnt.append(tmp)\n",
    "    \n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        ans = 0\n",
    "        can = defaultdict(list)\n",
    "        can[0].append(nums[0])\n",
    "        for i in range(1,n):\n",
    "            can[cnt[i]].append(nums[i])\n",
    "        for v in can:\n",
    "            ans = max(ans,sum(can[v]))\n",
    "        return ans\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumSum(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        # res = defaultdict(list)\n",
    "        res = Counter()\n",
    "        for i in range(1, n+1):\n",
    "            demo = i\n",
    "            c = 1\n",
    "            for j in range(2, isqrt(n)+1):\n",
    "                times = 0\n",
    "                while i % j == 0:\n",
    "                    i //= j\n",
    "                    times += 1\n",
    "                if times % 2: c *= j\n",
    "            if i > 1: c *= i\n",
    "            res[demo] = c\n",
    "        ans = 0\n",
    "        print(res)\n",
    "        s = [0] * (n+1)\n",
    "        for i,x in enumerate(nums):\n",
    "            s[res[i+1]] += x\n",
    "        return max(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        def max_cycle(fa: List[int]) -> int:\n",
    "            n = len(fa)\n",
    "            vis = [False] * n\n",
    "            ans = 0\n",
    "            for i in range(n):\n",
    "                if vis[i]:\n",
    "                    continue\n",
    "                cycle = []\n",
    "                j = i\n",
    "                while not vis[j]:\n",
    "                    cycle.append(j)\n",
    "                    vis[j] = True\n",
    "                    j = fa[j]\n",
    "                for k, v in enumerate(cycle):\n",
    "                    if v == j:\n",
    "                        ans = max(ans, len(cycle) - k)\n",
    "                        break\n",
    "            return ans\n",
    "\n",
    "        def topological_sort(fa: List[int]) -> int:\n",
    "            n = len(fa)\n",
    "            indeg = [0] * n\n",
    "            dist = [1] * n\n",
    "            for v in fa:\n",
    "                indeg[v] += 1\n",
    "            q = deque(i for i, v in enumerate(indeg) if v == 0)\n",
    "            while q:\n",
    "                i = q.popleft()\n",
    "                dist[fa[i]] = max(dist[fa[i]], dist[i] + 1)\n",
    "                indeg[fa[i]] -= 1\n",
    "                if indeg[fa[i]] == 0:\n",
    "                    q.append(fa[i])\n",
    "            return sum(dist[i] for i, v in enumerate(fa) if i == fa[fa[i]])\n",
    "\n",
    "        return max(max_cycle(favorite), topological_sort(favorite))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        n = len(favorite)\n",
    "        # 统计入度，便于进行拓扑排序\n",
    "        indeg = [0] * n\n",
    "        for i in range(n):\n",
    "            indeg[favorite[i]] += 1\n",
    "        \n",
    "        used = [False] * n\n",
    "        f = [1] * n\n",
    "        q = deque(i for i in range(n) if indeg[i] == 0)\n",
    "        \n",
    "        while q:\n",
    "            u = q.popleft()\n",
    "            used[u] = True\n",
    "            v = favorite[u]\n",
    "            # 状态转移\n",
    "            f[v] = max(f[v], f[u] + 1)\n",
    "            indeg[v] -= 1\n",
    "            if indeg[v] == 0:\n",
    "                q.append(v)\n",
    "        \n",
    "        # ring 表示最大的环的大小\n",
    "        # total 表示所有环大小为 2 的「基环内向树」上的最长的「双向游走」路径之和\n",
    "        ring = total = 0\n",
    "        for i in range(n):\n",
    "            if not used[i]:\n",
    "                j = favorite[i]\n",
    "                # favorite[favorite[i]] = i 说明环的大小为 2\n",
    "                if favorite[j] == i:\n",
    "                    total += f[i] + f[j]\n",
    "                    used[i] = used[j] = True\n",
    "                # 否则环的大小至少为 3，我们需要找出环\n",
    "                else:\n",
    "                    u = i\n",
    "                    cnt = 0\n",
    "                    while True:\n",
    "                        cnt += 1\n",
    "                        u = favorite[u]\n",
    "                        used[u] = True\n",
    "                        if u == i:\n",
    "                            break\n",
    "                    ring = max(ring, cnt)\n",
    "        \n",
    "        return max(ring, total)\n",
    "\n",
    "# 作者：力扣官方题解\n",
    "# 链接：https://leetcode.cn/problems/maximum-employees-to-be-invited-to-a-meeting/\n",
    "# 来源：力扣（LeetCode）\n",
    "# 著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        # 找出所有的环\n",
    "        num = len(favorite) # 员工个数\n",
    "        # 广度优先遍历，找出除了环之外的结构，并且积累f[i]\n",
    "        # f[i]: 以节点i为终点的最长路径（含i的节点个数），f[i] = max_j2i{f[j]}, if 不存在j->i, f[i]=1\n",
    "        # 广度优先遍历的时候，环上的点是入队列的，所有f[i]的路径全部不途经任何环\n",
    "        dp = [1]*num # f[i]\n",
    "        indeg = [0] *num # 第i个人被多少人喜欢\n",
    "        \n",
    "        for i in range(num):\n",
    "            indeg[favorite[i]] += 1 \n",
    "        queue = [i for i in range(num) if indeg[i]==0 ] # 没有别人喜欢他（指向他）\n",
    "        \n",
    "        # 广度优先遍历\n",
    "        visit = [0]*num\n",
    "        \n",
    "        while queue:\n",
    "            cur = queue.pop(0)\n",
    "            visit[cur] = 1\n",
    "            cur_favor = favorite[cur]\n",
    "            # 更新dp\n",
    "            dp[cur_favor] = max(dp[cur_favor], dp[cur]+1) # 环上的点不会喜欢环外的点！parent有环，因为cur不在环上，路径上不会有别的环上的点\n",
    "            indeg[cur_favor] -= 1\n",
    "            if indeg[cur_favor] == 0:\n",
    "                queue.append(cur_favor)\n",
    "        print(favorite)\n",
    "        print(visit)\n",
    "\n",
    "        # 这种机制下不存在无环的情况\n",
    "        # 如果是2环，积累下来，cumu = f[x] + f[y]\n",
    "        # 如果是>2环，算最大节点数\n",
    "        cnt, cnt2 = 0, 0\n",
    "        for i in range(num):\n",
    "            if visit[i] == 1: continue # 浏览过的不重复浏览，不是环的都已经浏览过了\n",
    "            j = favorite[i]\n",
    "            if favorite[j] == i: # 环为2\n",
    "                cnt2 += dp[i] + dp[j]\n",
    "                visit[i] = 1\n",
    "                visit[j] = 1\n",
    "            else:\n",
    "                head = i\n",
    "                tmp_cnt = 0\n",
    "                while True:\n",
    "                    tmp_cnt += 1\n",
    "                    visit[i] = 1\n",
    "                    i = favorite[i]\n",
    "                    if i == head: break\n",
    "                cnt = max(cnt, tmp_cnt)\n",
    "        return max(cnt, cnt2)\n",
    "        \n",
    "                    \n",
    "\n",
    "\n",
    "\n",
    "        \n",
    "            \n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from collections import deque\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: list[int]) -> int:\n",
    "        n=len(favorite)\n",
    "        deg=[0]*n\n",
    "        for i in favorite:\n",
    "            deg[i]+=1\n",
    "        branch=deque(i for i,j in enumerate(deg) if j==0)\n",
    "        tree=[[] for i in range(n)]\n",
    "        while branch:\n",
    "            x=branch.popleft()\n",
    "            y=favorite[x]\n",
    "            deg[y]-=1\n",
    "            if deg[y]==0:\n",
    "                branch.append(y)\n",
    "            tree[y].append(x)\n",
    "        res=0\n",
    "        im=[]\n",
    "        for i in range(n):\n",
    "            if deg[i]==0:\n",
    "                continue\n",
    "            a,b=1,i\n",
    "            while favorite[b]!=i:\n",
    "                a+=1\n",
    "                deg[b]=0\n",
    "                b=favorite[b]\n",
    "            deg[b]=0\n",
    "            if a>2:\n",
    "                res=max(res,a)\n",
    "            else:\n",
    "                im.append(i)\n",
    "        def bfs(x):\n",
    "            k=0\n",
    "            que=deque()\n",
    "            que.append(x)\n",
    "            while que:\n",
    "                k+=1\n",
    "                for i in range(len(que)):\n",
    "                    u=que.popleft()\n",
    "                    for j in tree[u]:\n",
    "                        que.append(j)\n",
    "            return k\n",
    "        summ=0\n",
    "        for i in im:\n",
    "            summ=summ+bfs(i)+bfs(favorite[i])\n",
    "        return max(summ,res)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        nodesout=[0]*len(favorite)\n",
    "        canuse=set(i for i in range(len(favorite)))\n",
    "        for i in range(len(favorite)):\n",
    "            nodesout[favorite[i]]+=1\n",
    "        q=[]\n",
    "        for i in range(len(nodesout)):\n",
    "            if nodesout[i]==0:\n",
    "                q.append(i)\n",
    "        dp=[1]*len(favorite)\n",
    "        while q:\n",
    "            node=q.pop(0)\n",
    "            canuse.remove(node)\n",
    "            dp[favorite[node]]=max(dp[favorite[node]],dp[node]+1)\n",
    "            nodesout[favorite[node]]-=1\n",
    "            if nodesout[favorite[node]]==0:\n",
    "                q.append(favorite[node])\n",
    "        res=0\n",
    "        tpmax=0\n",
    "        while canuse:\n",
    "            start=canuse.pop()\n",
    "            next=favorite[start]\n",
    "            if start==favorite[next]:\n",
    "                tpmax=tpmax+dp[start]+dp[next]\n",
    "                res=max(res,tpmax)\n",
    "                canuse.remove(next)\n",
    "            else:\n",
    "                loop=1\n",
    "                while start!=favorite[next]:\n",
    "                    canuse.remove(next)\n",
    "                    next=favorite[next]\n",
    "                    loop+=1\n",
    "                res=max(res,loop+1)\n",
    "                canuse.remove(next)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        n = len(favorite)\n",
    "        res = Counter()\n",
    "        for i,x in enumerate(favorite):\n",
    "            res[x] += 1\n",
    "\n",
    "        # 吭哧吭哧 找基环\n",
    "        vis = [False] * n  # 找环 由于重复访问过的节点不会出现其他的环 不必继续找这些\n",
    "        s = deque([i for i in range(n) if res[i]==0])\n",
    "        f = [1] * (n)\n",
    "        while s:\n",
    "            c = s.popleft()\n",
    "            vis[c] = True\n",
    "            v = favorite[c]\n",
    "            f[v] = max(f[v], f[c]+1)\n",
    "            res[v] -= 1\n",
    "            if res[v] == 0: s.append(v)            \n",
    "\n",
    "        ans = total = 0\n",
    "        for i in range(n):\n",
    "            if not vis[i]:\n",
    "                det = favorite[i]\n",
    "                if favorite[det] == i:\n",
    "                    total += f[i] + f[det]\n",
    "                    vis[i] = vis[det] = True\n",
    "                else:\n",
    "                    u = favorite[i]\n",
    "                    cnt = 1\n",
    "                    while u != i:\n",
    "                        cnt += 1\n",
    "                        u = favorite[u]\n",
    "                        vis[u] = True\n",
    "                    vis[u] = True\n",
    "                    ans = max(ans, cnt)\n",
    "        return max(ans, total)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        seen = [False]  * len(favorite)\n",
    "        ans = 0\n",
    "        for i, f in enumerate(favorite):\n",
    "            if not seen[i]:\n",
    "                length = 1\n",
    "                seen[i] = True\n",
    "                distance = {i: 0}\n",
    "                while not seen[f]:\n",
    "                    distance[f] = length\n",
    "                    length += 1\n",
    "                    seen[f] = True\n",
    "                    f = favorite[f]\n",
    "                if f in distance:\n",
    "                    ans = max(ans, length - distance[f])\n",
    "        n = len(favorite)\n",
    "        degree = [0] * n\n",
    "        for i, f in enumerate(favorite):\n",
    "            degree[f] += 1\n",
    "        nodes = set()\n",
    "        for i in range(n):\n",
    "            if i not in nodes and favorite[favorite[i]] == i:\n",
    "                nodes.add(i)\n",
    "                nodes.add(favorite[i])\n",
    "        distance = [1] * n\n",
    "        dq = deque()\n",
    "        for i, d in enumerate(degree):\n",
    "            if d == 0:\n",
    "                dq.append(i)\n",
    "        while dq:\n",
    "            u = dq.popleft()\n",
    "            v = favorite[u]\n",
    "            distance[v] = max(distance[v], distance[u] + 1)\n",
    "            degree[v] -= 1\n",
    "            if degree[v] == 0 and v not in nodes:\n",
    "                dq.append(v)\n",
    "        return max(ans, sum(distance[i] for i in nodes))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        n = len(favorite)\n",
    "        degrees = [0]*n\n",
    "        for i in range(n):\n",
    "            degrees[favorite[i]] += 1\n",
    "\n",
    "        f = [0]*n  # 代表最大路径长度。\n",
    "        edge = {}\n",
    "        for i in range(n):\n",
    "            edge[i] = favorite[i]\n",
    "\n",
    "        degree0 = []\n",
    "        for i in range(n):\n",
    "            if degrees[i] == 0:\n",
    "                degree0.append(i)\n",
    "\n",
    "        while degree0:\n",
    "            new_d0 = []\n",
    "            for t in degree0:\n",
    "                degrees[edge[t]] -= 1\n",
    "                if degrees[edge[t]] == 0:\n",
    "                    new_d0.append(edge[t])\n",
    "                f[edge[t]] = max(f[edge[t]], f[t]+1)\n",
    "            degree0 = new_d0\n",
    "\n",
    "        vis = [0]*n\n",
    "        ans2 = []\n",
    "        ansmore = 0\n",
    "        for i in range(n):\n",
    "            if not vis[i] and degrees[i]:\n",
    "                vis[i] = 1\n",
    "                l = 1\n",
    "                while not vis[edge[i]]:\n",
    "                    i = edge[i]\n",
    "                    l += 1\n",
    "                    vis[i] = 1\n",
    "                if l == 2:\n",
    "                    ans2.append(f[i]+f[edge[i]]+2)\n",
    "                else:\n",
    "                    ansmore = max(ansmore, l)\n",
    "\n",
    "        return max(sum(ans2), ansmore)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        n=len(favorite)\n",
    "        # print(list(enumerate(favorite)))\n",
    "        degd=Counter(favorite)\n",
    "        leafs=[k for k in range(n) if degd[k]==0]\n",
    "        # print(leafs)\n",
    "        # if len(leafs)==0:\n",
    "        #     return n\n",
    "        depth = [0]*n\n",
    "        classes = [-2]*n\n",
    "        duel_circle = {}\n",
    "        maxi_circle = 0\n",
    "        duel_cnt = 0\n",
    "        \n",
    "        def find_conn(node):\n",
    "            nonlocal maxi_circle,duel_cnt\n",
    "            this_conn=[]\n",
    "            this_conn_set=set()\n",
    "            while True:\n",
    "                if classes[node]>=0:\n",
    "                    case = 1\n",
    "                    break\n",
    "                elif node in this_conn_set:\n",
    "                    if node == favorite[favorite[node]]:\n",
    "                        classes[node] = node\n",
    "                        classes[favorite[node]] = favorite[node]\n",
    "                        duel_circle[node] = 0\n",
    "                        duel_circle[favorite[node]] = 0\n",
    "                        duel_cnt +=1\n",
    "                        case = 2 \n",
    "                    else:\n",
    "                        case = 3\n",
    "                    break\n",
    "                elif classes[node]==-1:\n",
    "                    case = 4\n",
    "                    break\n",
    "                else:\n",
    "                    this_conn.append(node)\n",
    "                    this_conn_set.add(node)\n",
    "                node = favorite[node]\n",
    "            # print(\"??\",node, case, this_conn)\n",
    "            if case==1 or case==2:\n",
    "                curcls = classes[node]\n",
    "                i = len(this_conn)-1 if case == 1 else len(this_conn)-3\n",
    "                cur = node\n",
    "                while i>=0:\n",
    "                    cur = this_conn[i]\n",
    "                    classes[cur]=curcls\n",
    "                    depth[cur]=depth[favorite[cur]]+1\n",
    "                    i-=1\n",
    "                duel_circle[classes[cur]] = max(depth[cur], duel_circle[classes[cur]])\n",
    "            if case == 3 or case == 4:\n",
    "                i = len(this_conn)-1\n",
    "                while i>=0:\n",
    "                    cur = this_conn[i]\n",
    "                    classes[cur]=-1\n",
    "                    if cur==node:\n",
    "                        maxi_circle = max(maxi_circle, len(this_conn)-i)\n",
    "                    i-=1\n",
    "            \n",
    "                    \n",
    "        for node in leafs:\n",
    "            find_conn(node)\n",
    "            # print(node,maxi_circle)\n",
    "            # print(depth)\n",
    "            # print(classes)\n",
    "            # print(duel_circle)\n",
    "        # maxi_duel = 0\n",
    "        # for k in duel_circle:\n",
    "        #     maxi_duel = max(2+duel_circle[k]+duel_circle[favorite[k]], maxi_duel)\n",
    "\n",
    "        for node in range(n):\n",
    "            if classes[node]==-2:\n",
    "                find_conn(node)\n",
    "                # print(node,maxi_circle)\n",
    "\n",
    "        return max(maxi_circle, sum(duel_circle.values())+duel_cnt*2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from collections import defaultdict, deque\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        n = len(favorite)  # 获取收到的邀请数量\n",
    "\n",
    "        # 初始化 in_degree 和 max_length 字典，分别用于记录每个节点的入度情况和最长链\n",
    "        in_degree, max_length = defaultdict(int), defaultdict(int)\n",
    "        for x in favorite:\n",
    "            in_degree[x] += 1  # 统计每个节点的入度情况\n",
    "\n",
    "        d = deque(i for i in range(n) if in_degree[i] == 0)  # 创建一个双端队列\n",
    "\n",
    "        # 拓扑排序：求基环外的最长链\n",
    "        while d:\n",
    "            cur = d.popleft()  # 从队列中取出一个节点\n",
    "            ne = favorite[cur]  # 找到当前节点的下一个节点\n",
    "            max_length[ne] = max(max_length[ne], max_length[cur] + 1)  # 更新最长链\n",
    "            in_degree[ne] -= 1  # 更新下一个节点的入度\n",
    "            if in_degree[ne] == 0:\n",
    "                d.append(ne)  # 如果下一个节点的入度为0，将其加入队列\n",
    "\n",
    "        # 圆桌最多放置一个大于 2 的环（ans1 统计最大值）\n",
    "        # 圆桌可放置多个等于 2 的环（ans2 累加该长度）\n",
    "        ans1, ans2 = 0, 0  # 初始化两个变量，用于统计结果\n",
    "\n",
    "        for i in range(n):\n",
    "            if in_degree[i] == 0:\n",
    "                continue  # 如果当前节点的入度为0，跳过此次循环\n",
    "\n",
    "            j, cur = favorite[i], 1\n",
    "            while j != i:\n",
    "                in_degree[j] = 0  # 一个环只需被处理一次，将环中其他节点的入度置0\n",
    "                j = favorite[j]  # 找到环中的下一个节点\n",
    "                cur += 1  # 增加当前环的长度\n",
    "\n",
    "            if cur == 2:\n",
    "                ans2 += 2 + max_length[i] + max_length[favorite[i]]\n",
    "            else:\n",
    "                ans1 = max(ans1, cur)  # 更新结果 ans1 为最大环的长度\n",
    "\n",
    "        # 返回计算得到的结果中的最大值\n",
    "        return max(ans1, ans2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        self.memory = [False] * len(favorite)\n",
    "        self.inEdges = [[] for _ in range(len(favorite))]\n",
    "        ans1, ans2 = 0, 0\n",
    "        for i in range(len(favorite)):\n",
    "            self.inEdges[favorite[i]].append(i)\n",
    "        for i in range(len(favorite)):\n",
    "            if not self.memory[i]:\n",
    "                value, flag = self.findMaxLength(favorite, i)\n",
    "                if flag:\n",
    "                    ans2 += value\n",
    "                else:\n",
    "                    ans1 = max(ans1, value)\n",
    "        return max(ans1, ans2)\n",
    "\n",
    "\n",
    "    def findMaxLength(self, favorite, current):\n",
    "        record = []\n",
    "        while not self.memory[current]:\n",
    "            self.memory[current] = True\n",
    "            record.append(current)\n",
    "            current = favorite[current]\n",
    "        count = 1\n",
    "        i = len(record) - 1\n",
    "        while record[i] != current:\n",
    "            count += 1\n",
    "            i -= 1\n",
    "        if count > 2:\n",
    "            self.bfs2(record)\n",
    "            return count, False\n",
    "        memory = set()\n",
    "        memory.add(record[-1])\n",
    "        memory.add(record[-2])\n",
    "        ans1, ans2 = self.bfs1(record[-1], memory), self.bfs1(record[-2], memory)\n",
    "        return max(ans1 + ans2, 2), True\n",
    "\n",
    "\n",
    "    def bfs1(self, current, memory):\n",
    "        q = deque()\n",
    "        q.append((current, 1))\n",
    "        ans = 1\n",
    "        while q:\n",
    "            top = q.popleft()\n",
    "            for node in self.inEdges[top[0]]:\n",
    "                if node not in memory:\n",
    "                    memory.add(node)\n",
    "                    self.memory[node] = True\n",
    "                    q.append((node, top[1] + 1))\n",
    "                    ans = max(ans, top[1] + 1)\n",
    "        return ans\n",
    "\n",
    "    def bfs2(self, record):\n",
    "        q = deque()\n",
    "        for node in record:\n",
    "            q.append(node)\n",
    "        while q:\n",
    "            top = q.popleft()\n",
    "            for node in self.inEdges[top]:\n",
    "                if not self.memory[node]:\n",
    "                    self.memory[node] = True\n",
    "                    q.append(node)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution: \n",
    "    def get_max_cycle_length(self, favorite: List[int]) -> int:\n",
    "        person_cnt = len(favorite)\n",
    "        max_cycle_length = 0\n",
    "\n",
    "        seen = set()\n",
    "\n",
    "        # for each person\n",
    "        for i in range(person_cnt):\n",
    "            # i - person i\n",
    "\n",
    "            # if person not part of any chain (chain with cycle)\n",
    "            if i in seen:\n",
    "                continue\n",
    "            \n",
    "            # begin of chain (chain with cycle)\n",
    "            begin_person = i\n",
    "\n",
    "            # visited nodes inside of chain (chain with cycle)\n",
    "            cur_visited = set()\n",
    "\n",
    "            # cur_person\n",
    "            cur_person = i\n",
    "\n",
    "            # try to build chain with cycle\n",
    "            while cur_person not in seen:\n",
    "                seen.add(cur_person)\n",
    "                cur_visited.add(cur_person)\n",
    "                cur_person = favorite[cur_person]\n",
    "            \n",
    "            # if cycle exists\n",
    "            if cur_person in cur_visited:\n",
    "                # length of chain with cycle\n",
    "                visited_person_cnt = len(cur_visited)\n",
    "\n",
    "                # try to find length of cycle\n",
    "                while begin_person != cur_person:\n",
    "                    visited_person_cnt -= 1\n",
    "                    begin_person = favorite[begin_person]\n",
    "            \n",
    "                max_cycle_length = max(max_cycle_length, visited_person_cnt)\n",
    "        \n",
    "        return max_cycle_length\n",
    "    \n",
    "    def get_max_chain_without_cycle_length(self, favorite: List[int]) -> int:\n",
    "        person_cnt = len(favorite)\n",
    "        max_chain_len = 0\n",
    "\n",
    "        # find mutal-favorite (a <-> b) pairs\n",
    "        pairs = []\n",
    "        visited = set()\n",
    "\n",
    "        for i in range(person_cnt):\n",
    "            if i not in visited and favorite[favorite[i]] == i:\n",
    "                pairs.append((i, favorite[i]))\n",
    "                visited.add(i)\n",
    "                visited.add(favorite[i])\n",
    "\n",
    "        # build deps list, list that consits from deps from i (a -> b and c -> b, we shoul build such list [a,c] for b)\n",
    "        deps = collections.defaultdict(list)\n",
    "        for i in range(person_cnt):\n",
    "            deps[favorite[i]].append(i)\n",
    "\n",
    "        for src, dst in pairs:\n",
    "            # max chain length to src\n",
    "            max_dist_to_src = 0\n",
    "            \n",
    "            q = collections.deque()\n",
    "            for dep in deps[src]:\n",
    "                if dep != dst: q.append((dep, 1)) # dependent node and dist to dependent node\n",
    "            \n",
    "            while q:\n",
    "                cur_dependency, dist = q.popleft()\n",
    "                max_dist_to_src = max(max_dist_to_src, dist)\n",
    "                for next_dep in deps[cur_dependency]:\n",
    "                    q.append((next_dep, dist + 1))\n",
    "            \n",
    "            max_dist_to_dst = 0\n",
    "            q = collections.deque()\n",
    "            for dep in deps[dst]:\n",
    "                if dep != src: q.append((dep, 1))\n",
    "            \n",
    "            while q:\n",
    "                cur_dependency, dist = q.popleft()\n",
    "                max_dist_to_dst = max(max_dist_to_dst, dist)\n",
    "                for next_dep in deps[cur_dependency]:\n",
    "                    q.append((next_dep, dist + 1)) \n",
    "\n",
    "            max_chain_len += 2 + max_dist_to_src + max_dist_to_dst\n",
    "\n",
    "        return max_chain_len\n",
    "\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        return max(self.get_max_cycle_length(favorite), self.get_max_chain_without_cycle_length(favorite))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        n = len(favorite)\n",
    "        inn = [0] * n \n",
    "        out = [[] for _ in range(n)]\n",
    "        myset = set([i for i in range(n)])\n",
    "        for i,x in enumerate(favorite):\n",
    "            out[x].append(i)\n",
    "            inn[x]+=1\n",
    "        \n",
    "        que = []\n",
    "        for i in range(n):\n",
    "            if inn[i]==0:\n",
    "                que.append(i)\n",
    "        \n",
    "        deep =[0] * n\n",
    "        h = 0\n",
    "        while que:\n",
    "            curLen = len(que)\n",
    "            h+=1\n",
    "            for _ in range(curLen):\n",
    "                i = que.pop(0)\n",
    "                myset.remove(i)\n",
    "                deep[favorite[i]] = max(deep[favorite[i]],h)\n",
    "                inn[favorite[i]]-=1\n",
    "                if inn[favorite[i]] == 0:\n",
    "                    que.append(favorite[i])\n",
    "        \n",
    "        two = 0\n",
    "        more = 0\n",
    "        while len(myset)!=0:\n",
    "            i = myset.pop()\n",
    "            if inn[i]!=0:\n",
    "                inn[i] = 0\n",
    "                next = favorite[i]\n",
    "                cnt = 1\n",
    "                while next!=i:\n",
    "                    myset.remove(next)\n",
    "                    inn[next] = 0\n",
    "                    cnt+=1\n",
    "                    next = favorite[next]\n",
    "\n",
    "                if cnt>2:\n",
    "                    more = max(more,cnt)\n",
    "                else:\n",
    "                    two += 2 + deep[i]+deep[favorite[i]]\n",
    "        \n",
    "        return max(two,more)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        n = len(favorite)\n",
    "        in_degree = [0] * n\n",
    "        edges = defaultdict(list)\n",
    "        for i, p in enumerate(favorite):\n",
    "            in_degree[p] += 1\n",
    "            edges[p].append(i)\n",
    "\n",
    "        zeros = []\n",
    "        for i, v in enumerate(in_degree):\n",
    "            if v == 0:\n",
    "                zeros.append(i)\n",
    "\n",
    "        paths = [0] * n\n",
    "        #dis = 1\n",
    "        while zeros:\n",
    "            nxt = []\n",
    "            for i in zeros:\n",
    "                in_degree[favorite[i]] -= 1\n",
    "                paths[favorite[i]] = max(paths[favorite[i]], paths[i] + 1)\n",
    "                if in_degree[favorite[i]] == 0:\n",
    "                    nxt.append(favorite[i])\n",
    "            zeros = nxt\n",
    "        \n",
    "        def getPath(cur):\n",
    "            path = []\n",
    "            while vis[cur] == 0:\n",
    "                path.append(cur)\n",
    "                vis[cur] = 1\n",
    "                cur = favorite[cur]\n",
    "            return path\n",
    "\n",
    "        def getLongestPath(cur):\n",
    "            return paths[cur]\n",
    "\n",
    "        vis = [0] * n\n",
    "        cycles = []\n",
    "        ans = 0\n",
    "        #print(in_degree)\n",
    "        #paths = list(in_degree)\n",
    "        #print(\"p\", paths)\n",
    "        c = 0\n",
    "        for i in range(n):\n",
    "            if vis[i] == 0 and in_degree[i] == 1:\n",
    "                path = getPath(i)\n",
    "                # cycles.append(path)\n",
    "                ans = max(ans, len(path))\n",
    "                if len(path) == 2:\n",
    "                    # find endpoint with longest paths\n",
    "                    x, y = path[0], path[1]\n",
    "                    a = getLongestPath(x)\n",
    "                    b = getLongestPath(y)\n",
    "                    c += a + b + 2\n",
    "        ans = max(ans, c)\n",
    "        return ans\n",
    "                \n",
    "\n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def fp(self, i, favorite):\n",
    "        global l, r1, r2\n",
    "        p = [i]\n",
    "        s = set([i])\n",
    "        j = favorite[i]\n",
    "        while j not in s and j not in l:\n",
    "            p.append(j)\n",
    "            s.add(j)\n",
    "            j = favorite[j]\n",
    "        if j in l:\n",
    "            if l[j][0] == 1:\n",
    "                p.append(j)\n",
    "                c = l[j][1]\n",
    "                for k in range(len(p)-2,-1,-1):\n",
    "                    l[p[k]] = [1, c, l[p[k+1]][2]+1]\n",
    "                    r1[c] = max([r1[c], l[p[k]][2]])\n",
    "            else:\n",
    "                for kk in range(len(p)):\n",
    "                    l[p[kk]] = [2, 0, 0]\n",
    "            return 0\n",
    "        elif j==p[-2]:\n",
    "            l[p[-1]] = [1, p[-1], 1]\n",
    "            l[p[-2]] = [1, p[-2], 1]\n",
    "            r1[p[-1]] = 1\n",
    "            r1[p[-2]] = 1\n",
    "            for k in range(len(p)-3,-1,-1):\n",
    "                l[p[k]] = [1, j, l[p[k+1]][2]+1]\n",
    "                r1[j] = max([r1[j], l[p[k]][2]])\n",
    "            return 1\n",
    "        else:\n",
    "            tmp = 1\n",
    "            for k in range(len(p)-1,-1,-1):\n",
    "                if p[k] == j:\n",
    "                    for kk in range(k,len(p)):\n",
    "                        l[p[kk]] = [2, 0, tmp]\n",
    "                    for kk in range(k):\n",
    "                        l[p[kk]] = [2, 0, 0]\n",
    "                    break\n",
    "                tmp += 1\n",
    "            r2 = max([r2, tmp])\n",
    "            return 2\n",
    "\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        global l, r1, r2\n",
    "        l = {}\n",
    "        r1 = {}\n",
    "        r2 = 0\n",
    "        n = len(favorite)\n",
    "        for i in range(n):\n",
    "            if i in l:\n",
    "                continue\n",
    "            self.fp(i, favorite)\n",
    "        t = 0\n",
    "        for k in r1:\n",
    "            t += r1[k]\n",
    "        return max([t, r2])\n",
    "\n",
    "            \n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        #此处寻找最大舔狗环\n",
    "        ans = 0\n",
    "        mark = [True for i in range(len(favorite))]\n",
    "        for i in range(len(favorite)):\n",
    "            if mark[i]:\n",
    "                mark_new = set()\n",
    "                road = []\n",
    "                dfs = [i]\n",
    "                while dfs:\n",
    "                    tmp = dfs.pop(0)\n",
    "                    if mark[tmp] and tmp not in mark_new:\n",
    "                        road.append(tmp)\n",
    "                        dfs.append(favorite[tmp])\n",
    "                        mark_new.add(tmp)\n",
    "                        mark[tmp] = False\n",
    "                    elif tmp in mark_new:\n",
    "                        for j in range(len(road)):\n",
    "                            if road[j] == tmp:\n",
    "                                ans = max(ans,len(road)-j)\n",
    "                    elif not mark[tmp]:\n",
    "                        break\n",
    "\n",
    "        #此处寻找所有舔狗集团\n",
    "        mark2 = [0 for i in range(len(favorite))]\n",
    "        #Mark2[i] = 互舔女神i的舔狗链长度\n",
    "        dic = defaultdict(list)\n",
    "        for i in range(len(favorite)):\n",
    "            dic[favorite[i]].append(i)\n",
    "        def tree(n):\n",
    "            if len(dic[n]) == 1:\n",
    "                return 1\n",
    "            stack = [(n,1)]\n",
    "            ma = 0\n",
    "            while stack:\n",
    "                tmp,cnt = stack.pop()\n",
    "                ma = max(ma,cnt)\n",
    "                for i in dic[tmp]:\n",
    "                    if tmp != favorite[n]:\n",
    "                        stack.append((i,cnt+1))\n",
    "            return ma\n",
    "\n",
    "                    \n",
    "        for i in range(len(favorite)):\n",
    "            if i == favorite[favorite[i]] and mark2[i] == 0:\n",
    "                mark2[i] = tree(i)\n",
    "                mark2[favorite[i]] = tree(favorite[i])\n",
    "        return max(ans,sum(mark2))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        l = len(favorite)\n",
    "        p_map = {}\n",
    "        for i,x in enumerate(favorite):\n",
    "            if x not in p_map:p_map[x]=[]\n",
    "            p_map[x].append(i)\n",
    "        visited = [0] * l \n",
    "        res = 0\n",
    "\n",
    "        def bfs(node,p_map,exclude):\n",
    "            res = 0\n",
    "            group = [node]\n",
    "            while group:\n",
    "                res += 1\n",
    "                tmp = []\n",
    "                for g in group:\n",
    "                    visited[g]=1\n",
    "                    if g in p_map:\n",
    "                        for gg in p_map[g]:\n",
    "                            if visited[gg]==1 or gg == exclude:continue\n",
    "                            tmp.append(gg)\n",
    "                group = tmp\n",
    "            return res\n",
    "        base = 0\n",
    "        for i in range(l):\n",
    "            if visited[i]==1:continue\n",
    "            if favorite[favorite[i]]==i: \n",
    "                circle = bfs(i,p_map,favorite[i]) + bfs(favorite[i],p_map,i)\n",
    "                res = max(res,circle)\n",
    "                base += circle\n",
    "        circle_res = res\n",
    "        for i in range(l):\n",
    "            if visited[i]==1:continue\n",
    "            circle = 0\n",
    "            node = i\n",
    "            step = 0\n",
    "            seq_map = {}\n",
    "            while visited[node]!=1:\n",
    "                visited[node]=1\n",
    "                seq_map[node]= step\n",
    "                step += 1\n",
    "                node = favorite[node]\n",
    "            if node in seq_map:\n",
    "                circle = step-seq_map[node]\n",
    "            res = max(res,circle)\n",
    "        return max(res,base) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from collections import defaultdict\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        ans = 0\n",
    "        in_use = [False]*len(favorite)\n",
    "        nei, adj = [], defaultdict(list)\n",
    "        for i in range(len(favorite)):\n",
    "            adj[favorite[i]].append(i)\n",
    "            if in_use[i]: continue\n",
    "            j = favorite[i]\n",
    "            if favorite[j] == i:\n",
    "                nei.append((i, j))\n",
    "                in_use[i] = in_use[j] = True\n",
    "        vis = [False]*len(favorite)\n",
    "        for ps in nei:\n",
    "            if vis[ps[0]]: continue\n",
    "            cur = 2\n",
    "            vis[ps[0]] = vis[ps[1]] = True\n",
    "            for i in ps:\n",
    "                t = 0\n",
    "                q, tmp = deque([i]), []\n",
    "                while q:\n",
    "                    j = q.popleft()\n",
    "                    for k in adj[j]:\n",
    "                        if not vis[k]:\n",
    "                            tmp.append(k)\n",
    "                            vis[k] = True\n",
    "                    if not q:\n",
    "                        q = deque(tmp)\n",
    "                        if tmp:\n",
    "                            t += 1\n",
    "                        tmp = []\n",
    "                cur += t\n",
    "            ans += cur\n",
    "        for i in range(len(favorite)):\n",
    "            if not vis[i]:\n",
    "                rec = dict()\n",
    "                j, k, = i, 0\n",
    "                while not vis[j]:\n",
    "                    vis[j] = True\n",
    "                    rec[j] = k\n",
    "                    k += 1\n",
    "                    j = favorite[j]\n",
    "                if rec.get(j, None) is not None:\n",
    "                    ans = max(ans, k-rec[j])\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        \n",
    "        # 如果a像b,要向后构造边(b -> a),使以下BFS更容易\n",
    "        invG = defaultdict(list)\n",
    "        for idx, fav in enumerate(favorite):\n",
    "            invG[fav].append(idx)\n",
    "        \n",
    "        # 求2-cycle扩展路径的函数\n",
    "        def bfs(start, seen):\n",
    "            q = deque([(start, 0)])\n",
    "            ans = 0 \n",
    "            while q:\n",
    "                pos, dist = q.popleft()\n",
    "                for neib in invG[pos]:\n",
    "                    if neib in seen:\n",
    "                        continue\n",
    "                    seen.add(neib)\n",
    "                    q.append((neib, dist+1))\n",
    "                    ans = max(ans, dist + 1)\n",
    "            return ans\n",
    "        \n",
    "        \n",
    "        N = len(favorite)\n",
    "        \n",
    "        # 由单个大循环和所有2-cycles导出的解\n",
    "        ans_large_cycle, ans_2_cycles = 0, 0 \n",
    "        \n",
    "        # 找到所有cycles\n",
    "        for i in range(N): \n",
    "            if favorite[i] != -1:  # 以前没有探索过，在这里做一个DFS\n",
    "                dist = {i: 0}  # 记录探索的顺序\n",
    "                while favorite[i] != -1:\n",
    "                    nxt = favorite[i]\n",
    "                    favorite[i] = -1\n",
    "                    if nxt in dist:  # 识别cycle\n",
    "                        cycle_len = len(dist) - dist[nxt]  # the real cycle length\n",
    "                        \n",
    "                        # 更新从单个大循环导出的解决方案\n",
    "                        ans_large_cycle = max(ans_large_cycle, cycle_len) \n",
    "                        \n",
    "                        # 更新由2-cycle及其扩展路径导出的解\n",
    "                        if cycle_len == 2: \n",
    "                            # I是当前顶点，NXT是下一个顶点\n",
    "                            ans_2_cycles += 2 + bfs(nxt, {i, nxt}) + bfs(i, {i, nxt}) \n",
    "                    else:\n",
    "                        i = nxt\n",
    "                        dist[nxt] = len(dist)\n",
    "\n",
    "        return max(ans_large_cycle, ans_2_cycles)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# 找环\n",
    "# 1.大于2的环：只包括环上的人\n",
    "# 2.等于2的环：包括环上的人，以及连接在环两端，最深的链上的人\n",
    "# 圆桌上可以坐，一个大于2的环，或者，所有等于2的环\n",
    "# 比较哪个人数多\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        indegree = defaultdict(int)\n",
    "        indegree_table = defaultdict(list)\n",
    "        n = len(favorite)\n",
    "        out_circle = set()\n",
    "        in_circle = set()\n",
    "        circles = []\n",
    "        f=[1]*n\n",
    "        for i in range(n):\n",
    "            indegree[favorite[i]] += 1\n",
    "            indegree_table[favorite[i]].append(i)\n",
    "        q = deque()\n",
    "        for i in range(n):\n",
    "            if indegree[i] == 0:\n",
    "                q.append(i)\n",
    "        while q:\n",
    "            node = q.popleft()\n",
    "            out_circle.add(node)\n",
    "            f[favorite[node]]=max(f[favorite[node]],f[node]+1)\n",
    "            indegree[favorite[node]] -= 1\n",
    "            if indegree[favorite[node]] == 0:\n",
    "                q.append(favorite[node])\n",
    "                out_circle.add(favorite[node])\n",
    "\n",
    "        for i in range(n):\n",
    "            if i not in out_circle and i not in in_circle:\n",
    "                c = []\n",
    "                while i not in in_circle:\n",
    "                    in_circle.add(i)\n",
    "                    c.append(i)\n",
    "                    i = favorite[i]\n",
    "                circles.append(c)\n",
    "        ans1,ans2 = 0,0\n",
    "        for circle in circles:\n",
    "            if len(circle) >= 3:\n",
    "                ans1 = max(ans1, len(circle))\n",
    "            elif len(circle) == 2:\n",
    "                ans2+=(f[circle[0]]+f[circle[1]])\n",
    "        return max(ans1,ans2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from typing import List\n",
    "'''\n",
    "一个公司准备组织一场会议，邀请名单上有 n 位员工。公司准备了一张 圆形 的桌子，可以坐下 任意数目 的员工。\n",
    "员工编号为 0 到 n - 1 。每位员工都有一位 喜欢 的员工，每位员工 当且仅当 他被安排在喜欢员工的旁边，他才会参加会议。每位员工喜欢的员工 不会 是他自己。\n",
    "给你一个下标从 0 开始的整数数组 favorite ，其中 favorite[i] 表示第 i 位员工喜欢的员工。请你返回参加会议的 最多员工数目 。\n",
    "n == favorite.length\n",
    "2 <= n <= 105\n",
    "0 <= favorite[i] <= n - 1\n",
    "favorite[i] != i\n",
    "'''\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        # 一定有环：环的大小和双向节点的路径大小\n",
    "        graph = {} # 建图\n",
    "        n = len(favorite)\n",
    "        for i in range(n):\n",
    "            graph[i] = []\n",
    "        count = [0] * n # 记录每个节点的度数\n",
    "        for i in range(n):\n",
    "            count[i] += 1\n",
    "            count[favorite[i]] += 1\n",
    "            graph[i].append(favorite[i])\n",
    "            graph[favorite[i]].append(i)\n",
    "        # 统计环的大小\n",
    "        f = {}\n",
    "        q = []\n",
    "        for i in range(n):\n",
    "            if count[i] == 1:\n",
    "                q.append([i, 1]) # 记录叶子结点\n",
    "                f[i] = 1\n",
    "        depth = 0\n",
    "        ans = 0\n",
    "        while q:\n",
    "            sz = len(q)\n",
    "            for i in range(sz):\n",
    "                x = q.pop()\n",
    "                for y in graph.get(x[0], []):\n",
    "                    count[y] -= 1\n",
    "                    if count[y] > 1:\n",
    "                        f[y] = max(x[1] + 1, f.get(y, 0))\n",
    "                    if count[y] == 1:\n",
    "                        f[y] = max(x[1] + 1, f.get(y, 0))\n",
    "                        q.append([y, f[y]])\n",
    "            depth += 1\n",
    "        count_2 =0\n",
    "        for i in range(n):\n",
    "            if count[i] > 1:\n",
    "                q1 = []\n",
    "                tmp = 1\n",
    "                q1.append(i)\n",
    "                count[i] = 0\n",
    "                l = []\n",
    "                l.append(i)\n",
    "                while q1:\n",
    "                    x = q1.pop()\n",
    "                    for y in graph.get(x, []):\n",
    "                        count[y] -= 1\n",
    "                        if count[y] == 1:\n",
    "                            l.append(y)\n",
    "                            q1.append(y)\n",
    "                            tmp += 1\n",
    "                if tmp == 2: # 如果环是2的话，是可以把连接的链加进来的\n",
    "                    sum_l = 0\n",
    "                    for z in l:\n",
    "                        max_l = 0\n",
    "                        for y in graph.get(z, []):\n",
    "                            if y in l:\n",
    "                                continue\n",
    "                            max_l = max(max_l, f.get(y, 0))\n",
    "                        sum_l += max_l\n",
    "                    ans = max(ans,tmp + sum_l + count_2)\n",
    "                    count_2 += sum_l + 2\n",
    "                else:\n",
    "                    ans = max(ans, tmp)\n",
    "        return ans\n",
    "s = Solution()\n",
    "print(s.maximumInvitations([5,13,3,14,1,1,13,13,14,10,5,13,3,14,2]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        n = len(favorite)\n",
    "        inv = defaultdict(list)\n",
    "        for i in range(n):\n",
    "            inv[favorite[i]].append(i)\n",
    "        # 检测2元环\n",
    "        vis = set()\n",
    "        binaryCircles = []\n",
    "        for i in range(n):\n",
    "            if i not in vis:\n",
    "                if favorite[favorite[i]] == i:\n",
    "                    binaryCircles.append((i, favorite[i]))\n",
    "                    vis |= {i, favorite[i]}\n",
    "        max_circle = 0\n",
    "        # 检测多元环\n",
    "        for i in range(n):\n",
    "            pos = {}\n",
    "            while i not in vis:\n",
    "                vis.add(i)\n",
    "                pos[i] = len(pos)\n",
    "                i = favorite[i]\n",
    "                if i in pos:\n",
    "                    max_circle = max(max_circle, len(pos) - pos[i])\n",
    "        total = 0\n",
    "        for circle in binaryCircles:\n",
    "            for x in circle:\n",
    "                layer = [x]\n",
    "                while layer:\n",
    "                    total += 1\n",
    "                    nxt = []\n",
    "                    for node in layer:\n",
    "                        for node2 in inv[node]:\n",
    "                            if node2 not in circle:\n",
    "                                nxt.append(node2)\n",
    "                    layer = nxt\n",
    "        return max(total, max_circle)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        n = len(favorite)\n",
    "        edges = defaultdict(list)\n",
    "        h = [0]*n\n",
    "        visi = set()\n",
    "        pos = defaultdict(int)\n",
    "        ans = 1\n",
    "        pair = set()\n",
    "        for i in range(n):\n",
    "            \n",
    "            if favorite[favorite[i]] == i:\n",
    "                pair.add(i)\n",
    "                pair.add(favorite[i])\n",
    "            else:\n",
    "                edges[favorite[i]].append(i)\n",
    "        visi.update(pair)\n",
    "        # print(edges)\n",
    "        for i in pair:\n",
    "            src = [i]\n",
    "            cnt = 1\n",
    "            while src:\n",
    "                visi.update(set(src))\n",
    "                nxt = []\n",
    "                cnt += 1\n",
    "                while src:\n",
    "                    j = src.pop()\n",
    "                    # for kk in edges[j]:\n",
    "                    #     if kk not in pair\n",
    "                    nxt.extend(edges[j])\n",
    "                src = nxt\n",
    "            pos[i] = cnt \n",
    "        \n",
    "        # print(pos)\n",
    "\n",
    "        def dfs(st):\n",
    "            visitmp = set()\n",
    "            cnt = 1\n",
    "            cur = st \n",
    "            visitmp.add(cur)\n",
    "            while favorite[cur] not in visitmp:\n",
    "                h[cur] = cnt\n",
    "                cnt += 1\n",
    "                visitmp.add(cur)\n",
    "                if favorite[cur] in pair:\n",
    "                    # pos[favorite[cur]] = cnt+1\n",
    "                    return cnt+1\n",
    "                else:\n",
    "                    cur = favorite[cur]\n",
    "            visi.update(visitmp)\n",
    "            return cnt - h[favorite[cur]] + 1\n",
    "\n",
    "        for i in range(n):\n",
    "            if i not in visi:\n",
    "                tmp = dfs(i)\n",
    "                # print(tmp,visi)\n",
    "                if tmp > ans :\n",
    "                    ans = tmp \n",
    "        # print(pos,pair)\n",
    "        pairkey = 0\n",
    "        # newvisi = {}\n",
    "        for i in pos:\n",
    "            # if i not in newvisi:\n",
    "            #     newvisi.add(i)\n",
    "            #     if favorite[i] in pos:\n",
    "            #         pairkey += pos[i] + pos[favorite[i]] - 4\n",
    "            #         newvisi.add(favorite[i])\n",
    "            #     else:\n",
    "            #         pairkey += pos[i] - 2\n",
    "            pairkey+=  pos[i]\n",
    "        pairkey += len(pair) - len(pos)*2\n",
    "        if ans < pairkey:\n",
    "            ans = pairkey\n",
    "\n",
    "\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        nin, already, cof, res = [set() for _ in range(len(favorite))], set(), [], 0\n",
    "        for i in range(len(favorite)):\n",
    "            if favorite[favorite[i]] == i:\n",
    "                cof.append(i)\n",
    "            else:\n",
    "                nin[favorite[i]].add(i)\n",
    "        for x in cof:\n",
    "            depth, queue = 0, [x]\n",
    "            while queue:\n",
    "                queueNext = []\n",
    "                for y in queue:\n",
    "                    already.add(y)\n",
    "                    for z in nin[y]:\n",
    "                        queueNext.append(z)\n",
    "                queue = queueNext[:]\n",
    "                depth += 1\n",
    "            res += depth\n",
    "        for i in range(len(favorite)):\n",
    "            if i not in already:\n",
    "                already.add(i)\n",
    "                dic, pres = {i: 0}, favorite[i]\n",
    "                while pres not in already:\n",
    "                    already.add(pres)\n",
    "                    dic[pres] = len(dic)\n",
    "                    pres = favorite[pres]\n",
    "                if pres in dic:\n",
    "                    res = max(res, len(dic) - dic[pres])\n",
    "                    print(dic)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        ans = 1\n",
    "        pair_cnt = 0\n",
    "        in_degree = defaultdict(set)\n",
    "        for i in range(len(favorite)):\n",
    "            in_degree[favorite[i]].add(i)\n",
    "        for i in range(len(favorite)):\n",
    "            if favorite[i] == -1:\n",
    "                continue\n",
    "            idx = favorite[i]\n",
    "            favorite[i] = -1\n",
    "            order = dict()\n",
    "            cnt = 0\n",
    "            order[i] = cnt\n",
    "            while favorite[idx] != -1:\n",
    "                cnt += 1\n",
    "                tmp = idx\n",
    "                order[idx] = cnt\n",
    "                idx = favorite[idx]\n",
    "                favorite[tmp] = -1\n",
    "            if tmp not in order or idx not in order:\n",
    "                continue\n",
    "            cnt = order[tmp] - order[idx] + 1\n",
    "            if cnt == 2:\n",
    "                a, b = idx, tmp\n",
    "                in_degree[a].discard(b)\n",
    "                in_degree[b].discard(a)\n",
    "                # a list\n",
    "                q = [a]\n",
    "                a_cnt = -1\n",
    "                while q:\n",
    "                    qlen = len(q)\n",
    "                    a_cnt += 1\n",
    "                    for j in range(qlen):\n",
    "                        node = q.pop(0)\n",
    "                        q += in_degree[node]\n",
    "\n",
    "                # b list\n",
    "                q = [b]\n",
    "                b_cnt = -1\n",
    "                while q:\n",
    "                    qlen = len(q)\n",
    "                    b_cnt += 1\n",
    "                    for j in range(qlen):\n",
    "                        node = q.pop(0)\n",
    "                        q += in_degree[node]\n",
    "                \n",
    "                pair_cnt += 2+a_cnt+b_cnt\n",
    "            ans = max(ans, cnt)\n",
    "        return max(ans, pair_cnt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        g = {}\n",
    "        used = set()\n",
    "        n = len(favorite)\n",
    "        res = 0\n",
    "        pair = []\n",
    "        for index in range(n):\n",
    "            if favorite[index] not in g:\n",
    "                g[favorite[index]] = set()\n",
    "            g[favorite[index]].add(index)\n",
    "\n",
    "            if index not in used:\n",
    "                used.add(index)\n",
    "                next = favorite[index]\n",
    "                stack = [index]\n",
    "                circle = set([index])\n",
    "                while next not in circle and next not in used:\n",
    "                    used.add(next)\n",
    "                    circle.add(next)\n",
    "                    stack.append(next)\n",
    "                    next = favorite[next]\n",
    "                \n",
    "                if next not in circle:\n",
    "                    continue\n",
    "\n",
    "                step = 0\n",
    "                while stack:\n",
    "                    now = stack.pop()\n",
    "                    step += 1\n",
    "                    if now == next:\n",
    "                        break\n",
    "\n",
    "                if step == 2:\n",
    "                    pair.append([now, favorite[now]])\n",
    "                else:\n",
    "                    res = max(res, step)\n",
    "\n",
    "        def bfs(start):\n",
    "            q = [start]\n",
    "            l = 0\n",
    "            r = 1\n",
    "            step = 0\n",
    "            while l < r:\n",
    "                step += 1\n",
    "                for now in q[l : r]:\n",
    "                    for next in g.get(now, set()):\n",
    "                        q.append(next)\n",
    "                \n",
    "                l, r = r, len(q)\n",
    "\n",
    "            return step\n",
    "\n",
    "        cnt = 0\n",
    "        for x, y in pair:\n",
    "            g[x].remove(y)\n",
    "            g[y].remove(x)\n",
    "            cnt += bfs(x) + bfs(y)\n",
    "\n",
    "        return max(res, cnt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from typing import List\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        visited = {}\n",
    "        can = {}\n",
    "        n = len(favorite)\n",
    "        twins = {}\n",
    "        ans = 0\n",
    "        mapping = {idx: f for idx, f in enumerate(favorite)}\n",
    "        for i in range(n):\n",
    "            if i not in visited:\n",
    "                tmpm = {i: 0}\n",
    "                cnt = 1\n",
    "                ne = mapping[i]\n",
    "                while ne not in visited:\n",
    "                    tmpm[ne] = cnt\n",
    "                    cnt += 1\n",
    "                    ne = mapping[ne]\n",
    "                    if ne in tmpm:\n",
    "                        l = len(tmpm)\n",
    "                        cur = len(tmpm) - tmpm[ne]\n",
    "                        if cur == 2:\n",
    "                            side = 0 if ne < mapping[ne] else 1\n",
    "                            cp = (min(ne, mapping[ne]), max(ne, mapping[ne]))\n",
    "                            if cp in twins:\n",
    "                                le, ri = twins[cp]\n",
    "                                if ne < mapping[ne]:\n",
    "                                    twins[cp] = (max(le, l), ri)\n",
    "                                else:\n",
    "                                    twins[cp] = (le, max(ri, l))\n",
    "                            else:\n",
    "                                if ne < mapping[ne]:\n",
    "                                    twins[cp] = (l, 2)\n",
    "                                else:\n",
    "                                    twins[cp] = (2, l)\n",
    "                            for t, j in tmpm.items():\n",
    "                                visited[t] = l - j\n",
    "                                can[t] = (cp, side)\n",
    "                            visited[mapping[ne]] = 2\n",
    "                            can[mapping[ne]] = (cp, 1 - side)\n",
    "                        else:\n",
    "                            for t, j in tmpm.items():\n",
    "                                if j < tmpm[ne]:\n",
    "                                    visited[t] = - 1\n",
    "                                else:\n",
    "                                    visited[t] = cur\n",
    "                            ans = max(ans, cur)\n",
    "                        break\n",
    "                else:\n",
    "                    if ne not in can:\n",
    "                        for t in tmpm:\n",
    "                            visited[t] = -1\n",
    "                    else:\n",
    "                        l = len(tmpm)\n",
    "                        cp, side = can[ne]\n",
    "                        le, ri = twins[cp]\n",
    "                        if side == 0:\n",
    "                            twins[cp] = (max(le, l + visited[ne]), ri)\n",
    "                        else:\n",
    "                            twins[cp] = (le, max(ri, l + visited[ne]))\n",
    "                        for t, j in tmpm.items():\n",
    "                            visited[t] = l - j + visited[ne]\n",
    "                            can[t] = (cp, side)\n",
    "        tmp = 0\n",
    "        for cp, (le, ri) in twins.items():\n",
    "            tmp += le + ri - 2\n",
    "        return max(ans, tmp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "\n",
    "        graph = collections.defaultdict(list)\n",
    "        reversed_graph = collections.defaultdict(list)\n",
    "        indeg = collections.defaultdict(int)\n",
    "\n",
    "        n = len(favorite)\n",
    "        for u, v in enumerate(favorite):\n",
    "            graph[u].append(v)\n",
    "            reversed_graph[v].append(u)\n",
    "            indeg[v] += 1\n",
    "        \n",
    "        deque = collections.deque([u for u in range(n) if indeg[u]==0])\n",
    "        while deque:\n",
    "            u = deque.popleft()\n",
    "            # for v in graph[u]:\n",
    "            v = favorite[u]\n",
    "            indeg[v] -= 1\n",
    "            if indeg[v] == 0:\n",
    "                deque.append(v)\n",
    "        \n",
    "        def bfs1(root):\n",
    "            depth = 0\n",
    "            deque = collections.deque([root])\n",
    "            while deque:\n",
    "                u = deque.popleft()\n",
    "                if u in visited:\n",
    "                    return depth\n",
    "                visited.add(u)\n",
    "                deque.append(favorite[u])\n",
    "                depth += 1\n",
    "\n",
    "\n",
    "        def dfs(u, depth):\n",
    "            if u in visited:\n",
    "                return depth\n",
    "            visited.add(u)\n",
    "            return dfs(favorite[u], depth+1)\n",
    "        \n",
    "        starts = [u for u in range(n) if indeg[u]>0]\n",
    "        visited = set()\n",
    "        records = []\n",
    "        max_circle_len = 0\n",
    "        # print(starts)\n",
    "        for u in starts:\n",
    "            if u in visited:\n",
    "                continue\n",
    "            # circle_len = dfs(u, 0)\n",
    "            circle_len = bfs1(u)\n",
    "            max_circle_len = max(max_circle_len, circle_len)\n",
    "            # print(u, circle_len, visited)\n",
    "            if circle_len==2:\n",
    "                records.append((u, favorite[u]))\n",
    "\n",
    "        if len(records) == 0:\n",
    "            return max_circle_len\n",
    "        \n",
    "        def dfs2(u, step):\n",
    "            if not reversed_graph[u]:\n",
    "                return step\n",
    "            return max(dfs2(child, step+1) for child in reversed_graph[u])\n",
    "        \n",
    "        max_depth = 0\n",
    "        def dfs2(u, depth):\n",
    "            nonlocal max_depth\n",
    "            max_depth = max(max_depth, depth)\n",
    "            for v in reversed_graph[u]:\n",
    "                dfs2(v, depth+1)\n",
    "\n",
    "        def bfs2(root):\n",
    "            depth = 0\n",
    "            deque = collections.deque([root])\n",
    "            while deque:\n",
    "                depth += 1\n",
    "                for _ in range(len(deque)):\n",
    "                    u = deque.popleft()\n",
    "                    for v in reversed_graph[u]:\n",
    "                        deque.append(v)\n",
    "            return depth\n",
    "\n",
    "        # print(records)\n",
    "        # print(reversed_graph)\n",
    "        pair_path_len = 0\n",
    "        while records:\n",
    "            u, v = records.pop()\n",
    "            reversed_graph[u] = [i for i in reversed_graph[u] if i!=v]\n",
    "            reversed_graph[v] = [i for i in reversed_graph[v] if i!=u]\n",
    "            # print(reversed_graph)\n",
    "            # max_depth = 0\n",
    "            # dfs2(u,1)\n",
    "            # left = max_depth\n",
    "            # max_depth = 0\n",
    "            # dfs2(v,1)\n",
    "            # right = max_depth\n",
    "            left = bfs2(u)\n",
    "            right = bfs2(v)\n",
    "            # left = dfs2(u,0)\n",
    "            # right = dfs2(v,0)\n",
    "            # print(left, right)\n",
    "            pair_path_len += left+right\n",
    "        \n",
    "        ans = max(max_circle_len, pair_path_len)\n",
    "        return ans\n",
    "\n",
    "        \n",
    "\n",
    "\n",
    "         \n",
    "\n",
    "        \n",
    "\n",
    "\n",
    "\n",
    "\n",
    "        \n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        # 有两种情况：\n",
    "        # 一个二元环和最多两个单相思链\n",
    "        # 一个环\n",
    "        n = len(favorite)\n",
    "        be_liked = defaultdict(set)\n",
    "        in_degree = defaultdict(int)\n",
    "        for i, c in enumerate(favorite):\n",
    "            be_liked[c].add(i)\n",
    "            in_degree[c] += 1\n",
    "\n",
    "        # 拓扑排序找到最长的单相思链\n",
    "        q = deque()\n",
    "        for i in range(n):\n",
    "            if in_degree[i] == 0:\n",
    "                q.append(i)\n",
    "        be_liked_length = defaultdict(int)\n",
    "        deep = 1\n",
    "        while q:\n",
    "            size = len(q)\n",
    "            for _ in range(size):\n",
    "                a = q.popleft()\n",
    "                b = favorite[a]\n",
    "                be_liked_length[a] = deep\n",
    "                in_degree[b] -= 1\n",
    "                if in_degree[b] == 0:\n",
    "                    q.append(b)\n",
    "            deep += 1\n",
    "        \n",
    "        ans = 1\n",
    "        # 二元环时不闭合的，所以二元环可以全部放进去\n",
    "        two_circle = 0\n",
    "        # 找环\n",
    "        for i in range(n):\n",
    "            if be_liked_length[i] == 0:\n",
    "                p = favorite[i]\n",
    "                cnt = 2\n",
    "                be_liked_length[i] = be_liked_length[p] = 1\n",
    "                # 二元环\n",
    "                if favorite[p] == i:\n",
    "                    cnt_i = 0\n",
    "                    for c in be_liked[i] - {p}:\n",
    "                        cnt_i = max(cnt_i, be_liked_length[c])\n",
    "                    cnt_p = 0\n",
    "                    for c in be_liked[p] - {i}:\n",
    "                        cnt_p = max(cnt_p, be_liked_length[c])\n",
    "                    # 两边都取最长的链\n",
    "                    cnt += cnt_i + cnt_p\n",
    "                    two_circle += cnt\n",
    "                    continue\n",
    "                cnt = 1\n",
    "                # 多元环\n",
    "                while p != i:\n",
    "                    cnt += 1\n",
    "                    p = favorite[p]\n",
    "                    be_liked_length[p] = 1\n",
    "                ans = max(ans, cnt)\n",
    "        return max(ans, two_circle)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        # 有两种情况：\n",
    "        # 一个二元环和最多两个单相思链\n",
    "        # 一个环\n",
    "        n = len(favorite)\n",
    "        be_liked = defaultdict(set)\n",
    "        in_degree = defaultdict(int)\n",
    "        for i, c in enumerate(favorite):\n",
    "            be_liked[c].add(i)\n",
    "            in_degree[c] += 1\n",
    "\n",
    "        # 拓扑排序找到最长的单相思链\n",
    "        q = deque()\n",
    "        for i in range(n):\n",
    "            if in_degree[i] == 0:\n",
    "                q.append(i)\n",
    "        be_liked_length = defaultdict(int)\n",
    "        deep = 1\n",
    "        while q:\n",
    "            size = len(q)\n",
    "            for _ in range(size):\n",
    "                a = q.popleft()\n",
    "                b = favorite[a]\n",
    "                be_liked_length[a] = deep\n",
    "                in_degree[b] -= 1\n",
    "                if in_degree[b] == 0:\n",
    "                    q.append(b)\n",
    "            deep += 1\n",
    "        \n",
    "        ans = 1\n",
    "        # 二元环时不闭合的，所以二元环可以全部放进去\n",
    "        two_circle = 0\n",
    "        # 找环\n",
    "        for i in range(n):\n",
    "            if be_liked_length[i] == 0:\n",
    "                p = favorite[i]\n",
    "                cnt = 2\n",
    "                be_liked_length[i] = be_liked_length[p] = 1\n",
    "                # 二元环\n",
    "                if favorite[p] == i:\n",
    "                    cnt_i = 0\n",
    "                    for c in be_liked[i] - {p}:\n",
    "                        cnt_i = max(cnt_i, be_liked_length[c])\n",
    "                    cnt_p = 0\n",
    "                    for c in be_liked[p] - {i}:\n",
    "                        cnt_p = max(cnt_p, be_liked_length[c])\n",
    "                    # 两边都取最长的链\n",
    "                    cnt += cnt_i + cnt_p\n",
    "                    two_circle += cnt\n",
    "                    continue\n",
    "                cnt = 1\n",
    "                # 多元环\n",
    "                while p != i:\n",
    "                    cnt += 1\n",
    "                    p = favorite[p]\n",
    "                    be_liked_length[p] = 1\n",
    "                ans = max(ans, cnt)\n",
    "        return max(ans, two_circle)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class UnionFind:\n",
    "    def __init__(self, n):\n",
    "        self.ancestors = [i for i in range(n)]\n",
    "\n",
    "    def find(self, a):\n",
    "        if a == self.ancestors[a]:\n",
    "            return a \n",
    "        self.ancestors[a] = self.find(self.ancestors[a])\n",
    "        return self.ancestors[a]\n",
    "\n",
    "    def merge(self, a, b):\n",
    "        aa = self.find(a)\n",
    "        ba = self.find(b)\n",
    "        self.ancestors[ba] = aa\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        n = len(favorite)\n",
    "        dp = [0] * n\n",
    "\n",
    "        # construct graph\n",
    "        graph = [[] for _ in range(n)]\n",
    "        indeg = [0] * n\n",
    "        for i in range(n):\n",
    "            graph[favorite[i]].append(i)\n",
    "            indeg[favorite[i]] += 1\n",
    "\n",
    "        # divide connecting components\n",
    "        uf = UnionFind(n)\n",
    "        for i in range(n):\n",
    "            uf.merge(i,favorite[i])\n",
    "        components = defaultdict(set)\n",
    "        for i in range(n):\n",
    "            components[uf.find(i)].add(i)\n",
    "\n",
    "        ans3 = 0\n",
    "        ans2 = 0\n",
    "        # for each components ...\n",
    "        for component in components.values():\n",
    "            nodes = deque([i for i in component if indeg[i] == 0])\n",
    "            while nodes:\n",
    "                cur = nodes.popleft()\n",
    "                dp[cur] = max([dp[i] for i in graph[cur]], default = 0) + 1\n",
    "                indeg[favorite[cur]] -= 1\n",
    "                if indeg[favorite[cur]] == 0:\n",
    "                    nodes.append(favorite[cur])\n",
    "\n",
    "            ring = [i for i in range(n) if i in component and indeg[i] > 0]\n",
    "            if len(ring) > 2:\n",
    "                this = len(ring)\n",
    "                ans3 = max(ans3, this)\n",
    "            else:\n",
    "                this = max([dp[i] for i in graph[ring[0]]], default = 0) + max([dp[i] for i in graph[ring[1]]], default = 0) + 2\n",
    "                ans2 += this\n",
    "                \n",
    "\n",
    "        return max(ans3, ans2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "class Node:\n",
    "    def __init__(self, i) -> None:\n",
    "        self.i = i\n",
    "        self.children = []\n",
    "        self.parents = []\n",
    "        self.neighbors = []\n",
    "        self.visited = False\n",
    "\n",
    "    def __hash__(self) -> int:\n",
    "        return self.i\n",
    "\n",
    "\n",
    "class Graph:\n",
    "    def __init__(self, n) -> None:\n",
    "        self.nodes = [Node(i) for i in range(n)]\n",
    "\n",
    "    def add_directed_edge(self, i, j):\n",
    "        self.nodes[i].children.append(self.nodes[j])\n",
    "        self.nodes[j].parents.append(self.nodes[i])\n",
    "\n",
    "    def add_undirected_edge(self, i, j):\n",
    "        self.nodes[i].neighbors.append(self.nodes[j])\n",
    "        self.nodes[j].neighbors.append(self.nodes[i])\n",
    "\n",
    "    \n",
    "class Solution:\n",
    "    def trace_parent(self, node, v):\n",
    "        parents = set(p.i for p in node.parents if not v[p.i])\n",
    "        length = 0\n",
    "        \n",
    "        while parents:\n",
    "            length += 1\n",
    "            new_parents = set()\n",
    "            for pi in parents:\n",
    "                v[pi] = True\n",
    "                for pp in self.graph.nodes[pi].parents:\n",
    "                    if not v[pp.i]:\n",
    "                        new_parents.add(pp.i)\n",
    "            if not new_parents:\n",
    "                break\n",
    "            parents = new_parents\n",
    "            \n",
    "\n",
    "        return length\n",
    "\n",
    "    def maximumInvitations(self, favorite) -> int:\n",
    "        n = len(favorite)\n",
    "        self.graph = Graph(n)\n",
    "\n",
    "        for i, j in enumerate(favorite):\n",
    "            self.graph.add_directed_edge(i, j)\n",
    "\n",
    "        total_length_pattern_1 = 0\n",
    "        total_length_pattern_2 = 0\n",
    "\n",
    "        visited = [False] * n\n",
    "\n",
    "        for i in range(n):\n",
    "            if visited[i]:\n",
    "                continue\n",
    "            \n",
    "            circle = [i]\n",
    "            cset = {i: 0}\n",
    "            # in this problem, one node has exactly one child\n",
    "            child_i = i\n",
    "            while True:\n",
    "                child_i = favorite[child_i]\n",
    "                if child_i in cset:\n",
    "                    break\n",
    "                circle.append(child_i)\n",
    "                cset[child_i] = len(circle) - 1\n",
    "\n",
    "            # print([node.i for node in circle])\n",
    "            # print(len(circle))\n",
    "            if len(circle) - cset[child_i] == 2:\n",
    "                node1, node2 = self.graph.nodes[circle[-2]], self.graph.nodes[circle[-1]]\n",
    "                visited[circle[-2]] = True\n",
    "                visited[circle[-1]] = True\n",
    "                trace1 = self.trace_parent(node1, visited)\n",
    "                trace2 = self.trace_parent(node2, visited)\n",
    "                total_length_pattern_1 += 2 + trace1 + trace2\n",
    "            else:\n",
    "                # len(circle) >= 3, since one cannot favor himself\n",
    "                for i in circle:\n",
    "                    visited[i] = True\n",
    "                total_length_pattern_2 = max(total_length_pattern_2, len(circle) - cset[child_i])\n",
    "\n",
    "        # print(total_length_pattern_1, total_length_pattern_2)\n",
    "        return max(total_length_pattern_1, total_length_pattern_2)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        n = len(favorite)\n",
    "\n",
    "        degree = [0]*n\n",
    "        inverse = [[] for _ in range(n)]\n",
    "        tail = [0]*n\n",
    "        for i in range(n):\n",
    "            degree[favorite[i]]+=1\n",
    "            inverse[favorite[i]].append(i)\n",
    "        \n",
    "        i = 0\n",
    "        while i<n:\n",
    "            x = i\n",
    "            while not degree[x]:\n",
    "                degree[x]-=1\n",
    "                x = favorite[x]\n",
    "                degree[x]-=1\n",
    "            i+=1\n",
    "        \n",
    "        visited = [False]*n\n",
    "        special = 0\n",
    "        res = 0\n",
    "\n",
    "        def help(i):\n",
    "            if tail[i]:\n",
    "                return tail[i]\n",
    "\n",
    "            if not inverse[i]:\n",
    "                tail[i] = 1\n",
    "                return 1\n",
    "            \n",
    "            tail[i] = max(help(j) for j in inverse[i])+1\n",
    "            return tail[i]\n",
    "\n",
    "        for i in range(n):\n",
    "            if degree[i]==-1 and tail[i]==0:\n",
    "                help(i)\n",
    "\n",
    "        for i in range(n):\n",
    "            if visited[i] or degree[i]==-1:\n",
    "                continue\n",
    "            x = i \n",
    "            length = 0\n",
    "            while not visited[x]:\n",
    "                visited[x] = True\n",
    "                x = favorite[x]\n",
    "                length+=1\n",
    "            if length==2:\n",
    "                special += 2+max(tail[j] for j in inverse[i])+max(tail[j] for j in inverse[favorite[i]])\n",
    "            else:\n",
    "                res = max(res, length)\n",
    "        return max(res, special)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        # 能做到一起的话有两种可能性, 一种是构成一个圈 另外一种是开头是两个人相互喜欢, 然后后面跟了一群喜欢的人\n",
    "        result = 0\n",
    "\n",
    "        # 首先寻找大圈, 如果把人与人之间的关系看做是一个图的话, 那么这个图的所有的元素的出度都是 1, 查找入度为0的点并且去除\n",
    "        liked_dict = defaultdict(set)\n",
    "        for like, liked in enumerate(favorite):\n",
    "            liked_dict[liked].add(like)\n",
    "        liked_dict_copy = copy.deepcopy(liked_dict)\n",
    "\n",
    "        tmp_list = [i for i in range(len(favorite)) if not liked_dict.get(i, set())]\n",
    "        # print(liked_dict)\n",
    "        # print(tmp_list)\n",
    "        while tmp_list:\n",
    "            tmp_list_2 = []\n",
    "            for i in tmp_list:\n",
    "                liked_liked = favorite[i]\n",
    "                liked_dict[liked_liked].remove(i)\n",
    "                if not liked_dict[liked_liked]:\n",
    "                    tmp_list_2.append(liked_liked)\n",
    "            tmp_list = tmp_list_2\n",
    "        other_num = set([i for i in liked_dict if liked_dict[i]])\n",
    "        tmp_set = set()\n",
    "        for i in other_num:\n",
    "            if i in tmp_set:\n",
    "                continue\n",
    "            num = 0\n",
    "            while i not in tmp_set:\n",
    "                # print(i)\n",
    "                num += 1\n",
    "                tmp_set.add(i)\n",
    "                i = favorite[i]\n",
    "            # print(\"-------\")\n",
    "            result = max(result, num)\n",
    "\n",
    "        # print(result)\n",
    "\n",
    "        # 计算两个人互相like 加上后面拖着一堆人的情况\n",
    "        pair_list = []\n",
    "        for i in range(len(favorite)):\n",
    "            j = favorite[i]\n",
    "            if favorite[j] == i and i < j:\n",
    "                pair_list.append([i, favorite[i]])\n",
    "        # print(pair_list)\n",
    "\n",
    "        result_2 = 0\n",
    "\n",
    "        for i, j in pair_list:\n",
    "            tmp = 2\n",
    "            tmp_list = []\n",
    "            for k in liked_dict_copy[i]:\n",
    "                if k != j:\n",
    "                    tmp_list.append(k)\n",
    "\n",
    "            while tmp_list:\n",
    "                tmp += 1\n",
    "                tmp_list_2 = []\n",
    "                for k in tmp_list:\n",
    "                    for l in liked_dict_copy[k]:\n",
    "                        tmp_list_2.append(l)\n",
    "                tmp_list = tmp_list_2\n",
    "\n",
    "            tmp_list = []\n",
    "            for k in liked_dict_copy[j]:\n",
    "                if k != i:\n",
    "                    tmp_list.append(k)\n",
    "            while tmp_list:\n",
    "                tmp += 1\n",
    "                tmp_list_2 = []\n",
    "                for k in tmp_list:\n",
    "                    for l in liked_dict_copy[k]:\n",
    "                        tmp_list_2.append(l)\n",
    "                tmp_list = tmp_list_2\n",
    "\n",
    "            result_2 += tmp\n",
    "        result = max(result, result_2)\n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        n = len(favorite)\n",
    "        a = list(range(n))\n",
    "        \n",
    "        def f(i):\n",
    "            if a[i] != i:\n",
    "                a[i] = f(a[i])\n",
    "            return a[i]\n",
    "        \n",
    "        for i in range(n):\n",
    "            a[f(i)] = f(favorite[i])\n",
    "        d = defaultdict(list)\n",
    "        for i in range(n):\n",
    "            d[f(i)].append(i)\n",
    "        m, s = 0, 0\n",
    "        \n",
    "        def f(a, i, j):\n",
    "            d = defaultdict(list)\n",
    "            for k in a:\n",
    "                d[favorite[k]].append(k)\n",
    "            d[i].remove(j)\n",
    "            d[j].remove(i)\n",
    "            \n",
    "            def f(i):\n",
    "                k, a = 0, [i]\n",
    "                while a:\n",
    "                    a = list(chain.from_iterable(d.pop(j) for j in a if j in d))\n",
    "                    k += 1\n",
    "                return k\n",
    "            \n",
    "            return f(i) + f(j)\n",
    "               \n",
    "        while d:\n",
    "            a = d.popitem()[1]\n",
    "            c, i = {}, a[0]\n",
    "            while i not in c:\n",
    "                c[i] = len(c)\n",
    "                i = favorite[i]\n",
    "            if (c := len(c) - c[i]) > 2:\n",
    "                m = max(m, c)\n",
    "                continue\n",
    "            s += f(a, i, favorite[i])\n",
    "        return max(m, s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        n = len(favorite)\n",
    "        ans = 0\n",
    "        degs = [0 for _ in range(n)]\n",
    "        deps = [1 for _ in range(n)]\n",
    "        dq = deque()\n",
    "        \n",
    "        for i in range(n):\n",
    "            degs[favorite[i]] += 1\n",
    "        \n",
    "        for i in range(n):\n",
    "            if degs[i] == 0:\n",
    "                dq.append(i)\n",
    "        \n",
    "        while len(dq) > 0:\n",
    "            #print(repr(dq))\n",
    "            cv = dq.popleft()\n",
    "            degs[favorite[cv]] -= 1\n",
    "            deps[favorite[cv]] = max(deps[favorite[cv]], deps[cv] + 1)\n",
    "            #print(repr(deps))\n",
    "            if degs[favorite[cv]] == 0:\n",
    "                dq.append(favorite[cv])\n",
    "        \n",
    "        def dfsr(i, cnt=0):\n",
    "            if degs[i] == -1:\n",
    "                return cnt\n",
    "            degs[i] = -1\n",
    "            return dfsr(favorite[i], cnt + 1)\n",
    "        \n",
    "        total = 0\n",
    "        for i in range(n):\n",
    "            if degs[i] > 0:\n",
    "                rlen = dfsr(i)\n",
    "                if rlen > 2:\n",
    "                    ans = max(ans, rlen)\n",
    "                else:\n",
    "                    total += deps[i] + deps[favorite[i]]\n",
    "        \n",
    "        #print(repr(deps))\n",
    "        return max(ans, total)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, g: List[int]) -> int:\n",
    "        n = len(g)\n",
    "        degree = [0]*n\n",
    "        for i in g:\n",
    "            degree[i] += 1\n",
    "        vis = [0]*n\n",
    "        lis = []\n",
    "        for i,v in enumerate(degree):\n",
    "            if v == 0:\n",
    "                lis.append([i,1])\n",
    "        q = deque(lis)\n",
    "        while q:\n",
    "            node,v = q.popleft()\n",
    "            vis[node] =-1\n",
    "            t_node = g[node]\n",
    "            degree[t_node] -=1\n",
    "            if degree[t_node] == 0:\n",
    "                v = max(vis[t_node],v)\n",
    "                vis[t_node] = 0\n",
    "                q.append([t_node,v+1])\n",
    "            else:\n",
    "                vis[t_node] = v\n",
    "        \n",
    "        ans = 0\n",
    "        ans1 = 0\n",
    "        def dfs(node):\n",
    "            \n",
    "            if degree[node] == 0:\n",
    "                return\n",
    "            res.append(vis[node])\n",
    "            vis[node] = -1\n",
    "            degree[node] -= 1\n",
    "            dfs(g[node])\n",
    "        for ind,val in enumerate(vis):\n",
    "            res = []\n",
    "            if val != -1:\n",
    "                dfs(ind)\n",
    "                if len(res) == 2:\n",
    "                    ans1+=2+sum(res)\n",
    "                else:\n",
    "                    ans = max(ans,len(res))\n",
    "\n",
    "\n",
    "        return max(ans1,ans)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        # 2 people circle\n",
    "        # circle love\n",
    "        n=len(favorite)\n",
    "        deg = [0]*n\n",
    "        len_map=defaultdict(int)\n",
    "        for i,v in enumerate(favorite):\n",
    "            deg[v]+=1\n",
    "        stack = []\n",
    "        for i in range(n):\n",
    "            if deg[i]==0:\n",
    "                stack.append([i,1])\n",
    "        while stack:\n",
    "            pop = stack.pop()\n",
    "            deg[favorite[pop[0]]]-=1\n",
    "            if deg[favorite[pop[0]]]==0:\n",
    "                length = pop[1]\n",
    "                if favorite[pop[0]] in len_map:\n",
    "                    length = max(length,len_map[favorite[pop[0]]])\n",
    "                \n",
    "                stack.append([favorite[pop[0]],length+1])\n",
    "            else:\n",
    "                len_map[favorite[pop[0]]] = max(len_map[favorite[pop[0]]],pop[1])\n",
    "        visited = set()\n",
    "        def dfs(idx,cnt):\n",
    "            if idx in visited:\n",
    "                return cnt\n",
    "            cnt+=1\n",
    "            visited.add(idx)\n",
    "            return dfs(favorite[idx],cnt)\n",
    "        cnt1=0\n",
    "        cnt2=0\n",
    "        for i in range(n):\n",
    "            if i not in visited and deg[i]==1:\n",
    "                cnt=dfs(i,0)\n",
    "                if cnt>2:\n",
    "                    cnt1=max(cnt1,cnt)\n",
    "                if cnt==2:\n",
    "                    cnt2+=len_map[i]\n",
    "                    cnt2+=len_map[favorite[i]]\n",
    "                    cnt2+=2\n",
    "        return max(cnt1,cnt2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        n = len(favorite)\n",
    "        debug = 0\n",
    "        maxone = 0\n",
    "        cirs2 = []\n",
    "        used = [0] * n\n",
    "        roots = [None] * n\n",
    "        othercirs = []\n",
    "        for i in range(n):\n",
    "            if used[i]:\n",
    "                continue\n",
    "            viewed = set()\n",
    "            now = i\n",
    "            while now not in viewed and not used[now]:\n",
    "                viewed.add(now)\n",
    "                used[now] = 1\n",
    "                now = favorite[now]\n",
    "            if now not in viewed or used[now] == -1:\n",
    "                continue\n",
    "            circle = []\n",
    "            while not circle or circle[0] != now:\n",
    "                circle.append(now)\n",
    "                used[now] = -1\n",
    "                roots[now] = [0,now]\n",
    "                now = favorite[now]\n",
    "            if len(circle) == 2:\n",
    "                cirs2.append(circle)\n",
    "            else:\n",
    "                othercirs.append(circle)\n",
    "                maxone = max(maxone,len(circle))\n",
    "            # return 0\n",
    "        if debug:\n",
    "            print(cirs2)\n",
    "            print(othercirs)\n",
    "            print(used)\n",
    "            print(maxone)\n",
    "        def _cal(i):\n",
    "            if not roots[i]:\n",
    "                dis,root = _cal(favorite[i])\n",
    "                roots[i] = [dis+1,root]\n",
    "            return roots[i]\n",
    "        maxdisarr = [0] * n\n",
    "        for i in range(n):\n",
    "            dis,root = _cal(i)\n",
    "            maxdisarr[root] = max(maxdisarr[root],dis)\n",
    "        if debug:\n",
    "            print(roots)\n",
    "            print(maxdisarr)\n",
    "        cnt = 0\n",
    "        for arr in cirs2:\n",
    "            base = 2\n",
    "            for x in arr:\n",
    "                base += maxdisarr[x]\n",
    "            cnt += base\n",
    "        return max(maxone,cnt)\n",
    "'''\n",
    "[2,2,1,2]\n",
    "[1,2,0]\n",
    "[3,0,1,4,1]\n",
    "[1,0,0,2,1,4,7,8,9,6,7,10,8]\n",
    "[1,0,3,2,5,6,7,4,9,8,11,10,11,12,10]\n",
    "[7,0,7,13,11,6,8,5,9,8,9,14,15,7,11,6]\n",
    "'''"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def find_list(self, g, x, solved):\n",
    "        res = 0\n",
    "        for u in g[x]:\n",
    "            if u not in solved:\n",
    "                solved.add(u)\n",
    "                res = max(res, self.find_list(g, u, solved) + 1)\n",
    "        return res\n",
    "\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        # u->v for u like v\n",
    "        # x1->x2, x2->x1, x3->x1, x4->x1, then result is 3, if x6->x5->x2, then result is 5, \n",
    "        # if x9->x8->x7->x2, then result is 6, ...\n",
    "        # x1->x2, x2->x3, x3->x1, then result is 3, if x4->x1, then result is still 3\n",
    "        n = len(favorite)\n",
    "        solved = set()\n",
    "        res = 0  # 所有x1->x2->x3->x1都不能组合和扩展，答案是3\n",
    "        res2 = 0 # 所有x1->x2->x1及其扩展xi->...->x1,xj->...->x2都可以组合\n",
    "        # 如x1->x2->x1,x3->x4->x3，则答案是4\n",
    "\n",
    "        g = [[] for i in range(n)]\n",
    "        for i in range(n):\n",
    "            u = favorite[i]\n",
    "            g[u].append(i)\n",
    "\n",
    "        for i in range(n):\n",
    "            u = favorite[i]\n",
    "            if favorite[u] == i and i not in solved:\n",
    "                solved.add(u)\n",
    "                solved.add(i)\n",
    "                res2 += 2 + self.find_list(g, u, solved) + self.find_list(g, i, solved)\n",
    "        \n",
    "        # print(solved, res2)\n",
    "        for i in range(n):\n",
    "            if i not in solved:\n",
    "                u = favorite[i]\n",
    "                cnt = 0\n",
    "                tmp = {i: cnt}\n",
    "                while u not in solved:\n",
    "                    cnt += 1\n",
    "                    tmp[u] = cnt \n",
    "                    solved.add(u)\n",
    "                    u = favorite[u]\n",
    "                # print(\"tmp=\",tmp, \"u=\", u)\n",
    "                if u in tmp:\n",
    "                    res = max(res, cnt + 1 - tmp[u])\n",
    "        \n",
    "        return max(res, res2)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        n = len(favorite)\n",
    "        edge = [[] for _ in range(n)]\n",
    "        rank = [0 for _ in range(n)]\n",
    "        for i in range(n):\n",
    "            edge[i].append(favorite[i])\n",
    "            rank[favorite[i]] += 1\n",
    "            print(i, favorite[i])\n",
    "\n",
    "        ans = 0\n",
    "        line_len = [0 for _ in range(n)]  # 线性\n",
    "        \n",
    "        de = deque()\n",
    "        # 初始叶子节点\n",
    "        for i in range(n):\n",
    "            if rank[i] == 0:\n",
    "                de.append(i)\n",
    "                # line_len[i] = 1\n",
    "\n",
    "        while de:\n",
    "            t = de.popleft()\n",
    "            for child in edge[t]:\n",
    "                rank[child] -= 1\n",
    "                if rank[child] == 0:\n",
    "                    de.append(child)\n",
    "                line_len[child] = max(line_len[child], line_len[t] + 1)    \n",
    "                # ans = max(line_len[child], ans)\n",
    "\n",
    "\n",
    "        two_site = 0\n",
    "        finded = [0 for _ in range(n)]\n",
    "        def dfs(root):\n",
    "            finded[root] = 1\n",
    "            if finded[favorite[root]] == 1:\n",
    "                return 1\n",
    "            temp = dfs(favorite[root]) + 1\n",
    "            return temp\n",
    "\n",
    "        for i in range(n):\n",
    "            if rank[i] and finded[i] == 0:\n",
    "                temp = dfs(i)\n",
    "                ans = max(temp, ans)\n",
    "                if temp == 2:\n",
    "                    two_site += line_len[i] + line_len[favorite[i]] + 2\n",
    "                else:\n",
    "                    line_len[i] = 0\n",
    "        return max(ans, two_site)\n",
    "\n",
    " \n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        n = len(favorite)\n",
    "        indeg = [0] * n\n",
    "        for f in favorite:\n",
    "            indeg[f] += 1\n",
    "        \n",
    "        rg = [[] for _ in range(n)]\n",
    "        q = deque(i for i, d in enumerate(indeg) if d == 0)\n",
    "        while q:\n",
    "            now = q.popleft()\n",
    "            like = favorite[now]\n",
    "            rg[like] += [now]\n",
    "            indeg[like] -= 1\n",
    "            if indeg[like] == 0:\n",
    "                q.append(like)\n",
    "        \n",
    "        def rgdfs(now: int) -> int:\n",
    "            max_d = 1\n",
    "            for son in rg[now]:\n",
    "                max_d = max(max_d, rgdfs(son) + 1)\n",
    "            return max_d\n",
    "        \n",
    "        max_ring = sum_chain = 0\n",
    "        for i, d in enumerate(indeg):\n",
    "            if d == 0:\n",
    "                continue\n",
    "            indeg[i] = 0\n",
    "            now_ring = 1\n",
    "            now = favorite[i]\n",
    "            while now != i:\n",
    "                indeg[now] = 0\n",
    "                now_ring += 1\n",
    "                now = favorite[now]\n",
    "            \n",
    "            if now_ring == 2:\n",
    "                sum_chain += rgdfs(i) + rgdfs(favorite[i])\n",
    "            else:\n",
    "                max_ring = max(max_ring, now_ring)\n",
    "        return max(max_ring, sum_chain)\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        n = len(favorite)\n",
    "        deg = [0] * n\n",
    "        for f in favorite:\n",
    "            deg[f] += 1 # 统计基环树每个节点的入度\n",
    "\n",
    "        rg = [[] for _ in range(n)] # 反图\n",
    "        q = deque(i for i , d in enumerate(deg) if d == 0)\n",
    "        while q: # 拓扑排序，减掉树上所有树枝\n",
    "            x = q.popleft()\n",
    "            y = favorite[x]\n",
    "            rg[y].append(x)\n",
    "            deg[y] -= 1\n",
    "            if deg[y] == 0:\n",
    "                q.append(y)\n",
    "        \n",
    "        # 通过反图 rg寻找树枝上最深的链\n",
    "        def rdfs(x: int) -> int:\n",
    "            res = 1\n",
    "            for y in rg[x]:\n",
    "                res = max(res, rdfs(y) + 1)\n",
    "            return res\n",
    "\n",
    "        max_ring_size = sum_chain_size = 0\n",
    "        for i, d in enumerate(deg):\n",
    "            if d == 0:\n",
    "                continue\n",
    "\n",
    "            # 遍历基环上的点\n",
    "            deg[i] = 0 # 将基环上的点的入度标记为0，避免重复访问\n",
    "            ring_size = 1\n",
    "            x = favorite[i]\n",
    "            while x != i:\n",
    "                deg[x] = 0\n",
    "                ring_size += 1\n",
    "                x = favorite[x]\n",
    "            if ring_size == 2:\n",
    "                sum_chain_size += rdfs(i) + rdfs(favorite[i])\n",
    "            else:\n",
    "                max_ring_size = max(max_ring_size, ring_size)\n",
    "        return max(max_ring_size, sum_chain_size)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        n = len(favorite)\n",
    "        deg = [0] * n\n",
    "        for f in favorite:\n",
    "            deg[f] += 1  # 统计基环树每个节点的入度\n",
    "\n",
    "        rg = [[] for _ in range(n)]  # 反图\n",
    "        q = deque(i for i, d in enumerate(deg) if d == 0)\n",
    "        while q:  # 拓扑排序，剪掉图上所有树枝\n",
    "            x = q.popleft()\n",
    "            y = favorite[x]  # x 只有一条出边\n",
    "            rg[y].append(x)\n",
    "            deg[y] -= 1\n",
    "            if deg[y] == 0:\n",
    "                q.append(y)\n",
    "\n",
    "        # 通过反图 rg 寻找树枝上最深的链\n",
    "        def rdfs(x: int) -> int:\n",
    "            max_depth = 1\n",
    "            for son in rg[x]:\n",
    "                max_depth = max(max_depth, rdfs(son) + 1)\n",
    "            return max_depth\n",
    "\n",
    "        max_ring_size = sum_chain_size = 0\n",
    "        for i, d in enumerate(deg):\n",
    "            if d == 0: continue\n",
    "\n",
    "            # 遍历基环上的点\n",
    "            deg[i] = 0  # 将基环上的点的入度标记为 0，避免重复访问\n",
    "            ring_size = 1  # 基环长度\n",
    "            x = favorite[i]\n",
    "            while x != i:\n",
    "                deg[x] = 0  # 将基环上的点的入度标记为 0，避免重复访问\n",
    "                ring_size += 1\n",
    "                x = favorite[x]\n",
    "\n",
    "            if ring_size == 2:  # 基环长度为 2\n",
    "                sum_chain_size += rdfs(i) + rdfs(favorite[i])  # 累加两条最长链的长度\n",
    "            else:\n",
    "                max_ring_size = max(max_ring_size, ring_size)  # 取所有基环长度的最大值\n",
    "        return max(max_ring_size, sum_chain_size)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        n = len(favorite)\n",
    "        deg = [0] * n\n",
    "        rg = [[] for _ in range(n)]\n",
    "        for x, y in enumerate(favorite):\n",
    "            rg[y].append(x)\n",
    "            deg[y] += 1\n",
    "\n",
    "        q = deque(i for i, d in enumerate(deg) if d == 0)\n",
    "        while q:\n",
    "            x = q.popleft()\n",
    "            y = favorite[x]\n",
    "            deg[y] -= 1\n",
    "            if deg[y] == 0:\n",
    "                q.append(y)\n",
    "\n",
    "        def rdfs(x: int) -> int:\n",
    "            m_depth = 1\n",
    "            for y in rg[x]:\n",
    "                if deg[y] == 0:\n",
    "                    m_depth = max(m_depth, rdfs(y) + 1)\n",
    "            return m_depth\n",
    "\n",
    "        \n",
    "        max_ring_size = sum_chine_size = 0\n",
    "        for i, d in enumerate(deg):\n",
    "            if d <= 0:\n",
    "                continue\n",
    "            res = 0\n",
    "            x = i\n",
    "            while True:\n",
    "                res += 1\n",
    "                deg[x] = -1\n",
    "                x = favorite[x]\n",
    "                if x == i:\n",
    "                    break\n",
    "            if res == 2:\n",
    "                sum_chine_size += rdfs(i) + rdfs(favorite[i])\n",
    "            else:\n",
    "                max_ring_size = max(max_ring_size, res)\n",
    "        \n",
    "        return max(max_ring_size, sum_chine_size)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        #答案分为两种情况： \n",
    "        #1. 有一对互相喜欢的员工， 这时候可以求员工1， 2 后边分别有多少个员工喜欢 （形成两条链）， 这两条链长即为答案\n",
    "        #2. 有一个环， 环长即为答案\n",
    "        #要注意如果只有一条链是不行的， 因为链首没有喜欢的人\n",
    "        #每个点相连形成的图为一个内向基环树， 因为每个点只有一条出边\n",
    "        #建一个反图， 还是拓扑排序， 不过原来找入度为0变成了找出度为0， 出度的from其实就是原来的to， 可以直接通过favorite找到\n",
    "        n = len(favorite)\n",
    "        outdeg = [0] * n\n",
    "        rg = [[] for _ in range(n)]\n",
    "        for x, y in enumerate(favorite):\n",
    "            rg[y].append(x)\n",
    "            outdeg[y] += 1\n",
    "        dq = deque([i for i in range(n) if outdeg[i] == 0])\n",
    "        while dq:\n",
    "            y = dq.popleft()\n",
    "            x = favorite[y]\n",
    "            outdeg[x] -= 1\n",
    "            if outdeg[x] == 0:\n",
    "                dq.append(x)\n",
    "        v = set()\n",
    "        ans = 0\n",
    "        cyc_ans = 0\n",
    "        cyc_link = 0\n",
    "        def dfs(x):\n",
    "            cur = 1\n",
    "            for y in rg[x]:\n",
    "                cur = max(cur, 1 + dfs(y))\n",
    "            return cur\n",
    "        print(rg)\n",
    "        #剩下的就是环, 遍历每个环\n",
    "        for i in range(n):\n",
    "            if outdeg[i] == 0 or i in v:\n",
    "                continue\n",
    "            sz = set()\n",
    "            x = i\n",
    "            while x not in sz:\n",
    "                sz.add(x)\n",
    "                rg[favorite[x]].remove(x)\n",
    "                x = favorite[x]\n",
    "            v |= sz\n",
    "            if len(sz) == 2:\n",
    "                ans1 = 0\n",
    "                for _ in range(2):\n",
    "                    x = sz.pop()\n",
    "                    ans1 += dfs(x)\n",
    "                cyc_link += ans1\n",
    "            elif len(sz) > 2:\n",
    "                ans = max(ans, len(sz))\n",
    "\n",
    "        return max(ans, cyc_link)\n",
    "\n",
    "\n",
    "\n",
    "            \n",
    "\n",
    "\n",
    "\n",
    "        \n",
    "        \n",
    "            \n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        nlen = len(favorite)\n",
    "        result = 0\n",
    "\n",
    "        # Find out the loop pair\n",
    "        accessed = [0 for _ in range(nlen)]\n",
    "        pairs = []\n",
    "        for i in range(nlen):\n",
    "            if accessed[i]:\n",
    "                continue\n",
    "            if favorite[favorite[i]] == i:\n",
    "                pairs.append([i, favorite[i]])\n",
    "                accessed[i], accessed[favorite[i]] = 1, 1\n",
    "\n",
    "        # Construct the follower array.\n",
    "        liked = [[] for _ in range(nlen)]\n",
    "        for i in range(nlen):\n",
    "            liked[favorite[i]].append(i)\n",
    "\n",
    "        # DFS to find the longest follower list (named as tail below)\n",
    "        tails_len = [0 for _ in range(nlen)]\n",
    "\n",
    "        def dfs(n, excluded=None):\n",
    "            # excluded argumetn to exclude its pair from search scope.\n",
    "            nonlocal tails_len\n",
    "            # max_tail_len = 0\n",
    "            if not liked[n]:\n",
    "                return\n",
    "            for i in liked[n]:\n",
    "                if i == excluded:\n",
    "                    continue\n",
    "                dfs(i)\n",
    "                tails_len[n] = max(tails_len[n], 1 + tails_len[i])\n",
    "\n",
    "        for pair in pairs:\n",
    "            dfs(pair[0], pair[1])\n",
    "            dfs(pair[1], pair[0])\n",
    "            result = result + 2 + tails_len[pair[0]] + tails_len[pair[1]]\n",
    "\n",
    "\n",
    "        # Search for the close loop if any.\n",
    "        accessed = [[0,-1] for _ in range(nlen)]\n",
    "        loop_cnt = 0\n",
    "        for i in range(nlen):\n",
    "            loop_cnt += 1\n",
    "            cur = i\n",
    "            if accessed[i][0] != 0:\n",
    "                continue\n",
    "            accessed[cur][0] = loop_cnt\n",
    "            accessed[cur][1] = 0\n",
    "            \n",
    "            while 1:\n",
    "                like = favorite[cur]\n",
    "\n",
    "                if accessed[like][0] == 0:\n",
    "                    accessed[like][1] = accessed[cur][1] + 1\n",
    "                    accessed[like][0] = loop_cnt\n",
    "                    cur = like\n",
    "                elif accessed[like][0] == loop_cnt:\n",
    "                    result = max(result, accessed[cur][1] - accessed[like][1] + 1)\n",
    "                    break\n",
    "                else:\n",
    "                    break\n",
    "\n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        \"\"\" 分类讨论 pseudotree的情况 \n",
    "        if pseudotree(circle) size > 2: maxRingSize = pseudotree size \n",
    "        if pseudotree(circle) size = 2: 对每个pseudotree的node反向找链, \n",
    "        对于多个基环长度等于2的基环树，每个基环树所对应的链，都可以拼在其余链的末尾，\n",
    "        因此可以将这些链全部拼成一个圆桌，其大小记作sumChainSize\n",
    "        ==> max(maxRingSize, sumChainSize)\n",
    "        \"\"\"\n",
    "\n",
    "        # reversely-directed rG, doesn't influence the circle \n",
    "        # the dfs will need to be rdfs  \n",
    "        rG = collections.defaultdict(list)\n",
    "        n = len(favorite)\n",
    "        indeg = [0] * n \n",
    "        for i in favorite:\n",
    "            indeg[i] += 1 \n",
    "\n",
    "        # make the rG and also pruning the indeg\n",
    "        # pseudotree nodes have indeg = 1, all leaf nodes have indeg = 0 \n",
    "        queue = collections.deque([i for i, j in enumerate(indeg) if not indeg[i]])\n",
    "        while queue:\n",
    "            u = queue.popleft()\n",
    "            v = favorite[u]\n",
    "            rG[v].append(u) \n",
    "            indeg[v] -= 1 \n",
    "            if not indeg[v]: \n",
    "                queue.append(v) \n",
    "\n",
    "        # reverse DFS, get the depth of chain from each of the two nodes \n",
    "        def rdfs(x):\n",
    "            max_ = 1 \n",
    "            for v in rG[x]:\n",
    "                max_ = max(rdfs(v)+1, max_) \n",
    "            return max_ \n",
    "\n",
    "        maxRingSize, sumChainSize = 0, 0 \n",
    "        for u, d in enumerate(indeg):\n",
    "            # only search for the pesudotree nodes \n",
    "            if d == 0:\n",
    "                continue \n",
    "\n",
    "            indeg[u] = 0  # vis array \n",
    "            temp_ringsize = 1\n",
    "            x = favorite[u] \n",
    "            while x != u:\n",
    "                indeg[x] = 0  # vis array \n",
    "                temp_ringsize += 1 \n",
    "                x = favorite[x] \n",
    "            \n",
    "            if temp_ringsize == 2:  # combine rdfs results \n",
    "                sumChainSize += rdfs(u) + rdfs(favorite[u]) \n",
    "            else:\n",
    "                maxRingSize = max(maxRingSize, temp_ringsize)\n",
    "\n",
    "        return max(maxRingSize, sumChainSize)\n",
    "\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        g = defaultdict(list) \n",
    "        n = len(favorite)\n",
    "        indeg = [0] * n \n",
    "        for i in range(n):\n",
    "            g[i].append(favorite[i]) \n",
    "            indeg[favorite[i]] += 1 \n",
    "        circle = [1] * n \n",
    "        D = [0] * n \n",
    "        Q = deque()\n",
    "        for i in range(n):\n",
    "            if indeg[i] == 0:\n",
    "                Q.append(i)\n",
    "        \n",
    "        while Q:\n",
    "            u = Q.popleft()\n",
    "            circle[u] = 0 \n",
    "            for v in g[u]:\n",
    "                indeg[v] -= 1\n",
    "                D[v] = max(D[v], D[u] + 1) \n",
    "                if indeg[v] == 0:\n",
    "                    Q.append(v)\n",
    "        vis = [0] * n \n",
    "        def dfs(u):\n",
    "            vis[u] = 1 \n",
    "            tot = 1 \n",
    "            for v in g[u]:\n",
    "                if not vis[v]:\n",
    "                    tot += dfs(v) \n",
    "            return tot \n",
    "        ans = 0 \n",
    "        mx = 0 \n",
    "        for i in range(n):\n",
    "            if circle[i] == 1 and not vis[i]: \n",
    "                x = dfs(i)\n",
    "                mx = max(mx, x) \n",
    "                if x == 2:\n",
    "                    ans += 2 + D[i] + D[g[i][0]] \n",
    "        return max(ans, mx) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "'''必须存在成环状或者存在互相喜欢才能有人参加'''\n",
    "\n",
    "class Solution:\n",
    "    def maximumInvitations(self, favorite: List[int]) -> int:\n",
    "        n=len(favorite)\n",
    "        g=[[] for _ in range(n)]\n",
    "        for i,x in enumerate(favorite):\n",
    "            g[x].append(i)\n",
    "\n",
    "\n",
    "        def dfs(cur:int,pa:int)->int:\n",
    "            if cur==pa:return -inf\n",
    "            ret=0\n",
    "            for nxt in g[cur]:\n",
    "                ret=max(ret,dfs(nxt,pa))\n",
    "            return ret+1\n",
    "        \n",
    "        ans1=ans2=0 #ans1：大于等于3的环状链。ans2:相互喜欢的人数对。（三人以上成环状）与（相互喜欢+各自被单恋的舔狗人数）互斥\n",
    "        attended=set()\n",
    "        vis=[False]*n   #标记已经检索过的发起人\n",
    "        for i in range(n):\n",
    "            if not vis[i]:\n",
    "                vis[i]=True\n",
    "                path=1\n",
    "                if not vis[favorite[i]]:\n",
    "                    next=favorite[i]\n",
    "                    while not vis[next]:#未检索的员工进行标记，并获得有效的暗恋链长度\n",
    "                        path+=1\n",
    "                        vis[next]=True\n",
    "                        next=favorite[next]\n",
    "                    enter=next\n",
    "                    next=favorite[enter]\n",
    "                    cnt=1\n",
    "                    while enter!=next and cnt<2*path:   #找环状成员，第二个比较用来防止陷入死循环\n",
    "                        next=favorite[next]\n",
    "                        cnt+=1\n",
    "                    if cnt<=path and next not in attended:  #该暗恋环未被统计且属于有效环\n",
    "                        attended.add(next)\n",
    "                        if next==favorite[favorite[next]]:\n",
    "                            attended.add(favorite[next])\n",
    "                            a=max(0,dfs(next,favorite[next])-1)\n",
    "                            b=max(0,dfs(favorite[next],next)-1)\n",
    "                            ans1+=2+a+b\n",
    "                        else:\n",
    "                            start=next\n",
    "                            next=favorite[next]\n",
    "                            steps=1\n",
    "                            while next!=start:\n",
    "                                attended.add(next)\n",
    "                                next=favorite[next]\n",
    "                                steps+=1\n",
    "                            ans2=max(ans2,steps)\n",
    "\n",
    "        return max(ans1,ans2)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def captureForts(self, forts: List[int]) -> int:\n",
    "        if len(forts) == 1:\n",
    "            return 0\n",
    "        left, right = 0, 1\n",
    "        maximum = 0\n",
    "        while right < len(forts):\n",
    "            if forts[left] in [1, -1]:\n",
    "                while right < len(forts) and forts[right] == 0:\n",
    "                    right += 1\n",
    "                if right < len(forts) and forts[right] != forts[left]:\n",
    "                    maximum = max(maximum, right - left - 1)\n",
    "                left, right = right, right + 1\n",
    "            else:\n",
    "                left, right = left + 1, right + 1\n",
    "        return maximum\n",
    "                    \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumUniqueSubarray(self, nums: List[int]) -> int:\n",
    "        l,r = 0,0\n",
    "        visited = [False] * 10001\n",
    "        res = 0\n",
    "        cur = 0\n",
    "        while r<len(nums):\n",
    "            while visited[nums[r]]:\n",
    "                cur -= nums[l]\n",
    "                visited[nums[l]] = False\n",
    "                l += 1\n",
    "            cur += nums[r]\n",
    "            visited[nums[r]] = True\n",
    "            res = max(res,cur)\n",
    "            r+=1\n",
    "\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumUniqueSubarray(self, nums: List[int]) -> int:\n",
    "        res = 0\n",
    "        stack = []\n",
    "        sum_s = 0\n",
    "        while len(nums) != 0:\n",
    "            if nums[-1] not in stack:\n",
    "                stack.append(nums.pop())\n",
    "                sum_s += stack[-1]\n",
    "                res = max(res, sum_s)\n",
    "            else:\n",
    "                sum_s -= stack[0]\n",
    "                del stack[0]         \n",
    "        return res\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumUniqueSubarray(self, nums: List[int]) -> int:\n",
    "        if len(set(nums)) == len(nums):\n",
    "            return sum(nums)\n",
    "        \n",
    "        left, right = 0, 1\n",
    "        curSet = set([nums[0]])\n",
    "        maxScore, curScore = nums[0], nums[0]\n",
    "        while right < len(nums):\n",
    "            if nums[right] not in curSet:\n",
    "                curSet.add(nums[right])\n",
    "                # curScore += nums[right]\n",
    "            else:\n",
    "                while nums[left] != nums[right]:\n",
    "                    # print(curSet, '------', nums[left], nums[right], left, right, '1111111')\n",
    "                    curSet.remove(nums[left])\n",
    "                    left += 1\n",
    "                    # print(curSet, nums[left], nums[right], left, right, '2222222')\n",
    "                    \n",
    "                left += 1\n",
    "            right += 1\n",
    "                # curScore = sum(nums[left:right+1])\n",
    "            \n",
    "            # print(curSet, 'zzzz')\n",
    "            maxScore = max(maxScore, sum(curSet))\n",
    "        \n",
    "        return maxScore"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumUniqueSubarray(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        if n==0:return 0\n",
    "        if n==1:return nums[0]\n",
    "        s,left = 0,0\n",
    "        sets =set()\n",
    "        max_val = 0  \n",
    "        for right in range(0,n):\n",
    "            if nums[right] in sets:\n",
    "                while nums[right]!=nums[left]:\n",
    "                    s -= nums[left]\n",
    "                    sets.remove(nums[left])\n",
    "                    left+=1\n",
    "                left+=1\n",
    "            else:\n",
    "                s +=nums[right]\n",
    "                sets.add(nums[right])\n",
    "            max_val = max(max_val,s)\n",
    "            print(right,s )\n",
    "        return max_val\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumUniqueSubarray(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        nums.append(0)\n",
    "        dic = {}\n",
    "        p,ret = -1 , 0\n",
    "        for i in range(n):\n",
    "            p = max(p,dic.get(nums[i],-1))\n",
    "            dic[nums[i]]  = i \n",
    "            nums[i] += nums[i-1]\n",
    "            ret = max(nums[i] - nums[p],ret)\n",
    "        return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumUniqueSubarray(self, nums: List[int]) -> int:\n",
    "        # 含有 若干不同元素 的子数组 的和\n",
    "        # 滑动窗口\n",
    "\n",
    "        left,res = 0,0\n",
    "        cnt = defaultdict(int) # 标配用来记录当前每个数字出现的次数\n",
    "        sum_ = 0\n",
    "        for right,num in enumerate(nums):\n",
    "            cnt[num]+=1 # 二话不说，直接哈希表统计\n",
    "            sum_ += num # 题目得分是和的概念，所以来一个sum_统计一下和\n",
    "            if cnt[num]==1: #满足条件（加入新对象后，也没有重复的。注意，这里是配合后面使用的，因为后续的while,剔除了重复的部分）\n",
    "                res = max(res,sum_)\n",
    "            while cnt[num]>1: # 如果出现重复，开始移动窗口\n",
    "                cnt[nums[left]]-=1\n",
    "                sum_ -= nums[left]\n",
    "                # if cnt[nums[left]]==0:\n",
    "                #     del cnt[nums[left]]\n",
    "                left+=1\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumUniqueSubarray(self, nums: List[int]) -> int:\n",
    "        sum_ = 0\n",
    "        max_ = 0\n",
    "        hash = {}\n",
    "        start = 0\n",
    "        for end in range(len(nums)):\n",
    "            sum_ += nums[end]\n",
    "            hash[nums[end]] = hash.get(nums[end], 0) + 1\n",
    "            if len(hash) == end - start + 1:\n",
    "                max_ = max(sum_, max_)\n",
    "            while len(hash) < end - start + 1:\n",
    "                head = nums[start]\n",
    "                hash[head] -= 1\n",
    "                if hash[head] == 0:\n",
    "                    del hash[head]\n",
    "                sum_ -= nums[start]\n",
    "                start += 1\n",
    "        return max_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumUniqueSubarray(self, nums: List[int]) -> int:\n",
    "\n",
    "        lst = set()\n",
    "        n = len(nums)\n",
    "        l = r = ans = cnt = 0\n",
    "        while r < n:\n",
    "            while l < r and nums[r] in lst:\n",
    "                cnt -= nums[l]\n",
    "                lst.remove(nums[l])\n",
    "                l += 1\n",
    "            lst.add(nums[r])\n",
    "            cnt += nums[r]\n",
    "            ans = max(ans, cnt)\n",
    "            r += 1\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumUniqueSubarray(self, nums: List[int]) -> int:\n",
    "        cnt=Counter()\n",
    "        ans=left=sum_=0\n",
    "\n",
    "        for right,val in enumerate(nums):\n",
    "            cnt[val]+=1\n",
    "            sum_+=val\n",
    "            \n",
    "\n",
    "\n",
    "            while cnt[val] > 1:\n",
    "                cnt[nums[left]]-=1\n",
    "                sum_-=nums[left]\n",
    "                if cnt[nums[left]]==0:\n",
    "                    cnt.pop(nums[left])\n",
    "                left+=1\n",
    "            ans=max(ans,sum_)\n",
    "        return ans\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumUniqueSubarray(self, nums: List[int]) -> int:\n",
    "        \"\"\"\n",
    "        data structure: 序列，列表\n",
    "        algorithm:\n",
    "            不定长度滑动窗口\n",
    "            滑动方式\n",
    "                j+=1，i当不满足题目条件时候移动至满足条件为止\n",
    "        speical:\n",
    "\n",
    "        \"\"\"\n",
    "        #数字计数表\n",
    "        digit_set=set()\n",
    "        max_sum = 0\n",
    "        interval_sum = 0\n",
    "        i = 0\n",
    "        for j, num in enumerate(nums):\n",
    "            if num in digit_set:#目前窗口发现重复数字,计数并滑动\n",
    "                #发现重复元素后计数\n",
    "                max_sum = max(interval_sum ,max_sum)\n",
    "                while num in digit_set:#移动到无与当前值重复的元素,即左边界收缩到满足题目条件后再移动\n",
    "                    digit_set.remove(nums[i])\n",
    "                    interval_sum -= nums[i]\n",
    "                    i += 1\n",
    "            elif  j ==len(nums) - 1:#最后一个元素不是重复元素,仍需要一次额外的累加和计数\n",
    "                interval_sum  += num\n",
    "                max_sum = max(interval_sum ,max_sum)\n",
    "            #先进行判断，最后再累加和添加进set\n",
    "            interval_sum  += num\n",
    "            digit_set.add(num) \n",
    "        return max_sum"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumUniqueSubarray(self, nums: List[int]) -> int:\n",
    "        max=0\n",
    "        dic={}\n",
    "        begin=0\n",
    "        sum=0\n",
    "        for i in range(len(nums)):\n",
    "            sum+=nums[i]\n",
    "            dic[nums[i]]=dic.get(nums[i],0)+1\n",
    "            while dic[nums[i]]>1:\n",
    "                dic[nums[begin]]-=1\n",
    "                sum-=nums[begin]\n",
    "                begin+=1\n",
    "            if sum>max:\n",
    "                max=sum\n",
    "        return max\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumUniqueSubarray(self, nums: List[int]) -> int:\n",
    "\n",
    "        n = len(nums)\n",
    "        ans = 0\n",
    "        cnt = Counter()\n",
    "        left = 0\n",
    "        sum_ = 0\n",
    "        \n",
    "        for right, x in enumerate(nums):\n",
    "            #print(left,right,cnt,ans,x)\n",
    "            while cnt[x] == 1:\n",
    "                sum_ -= nums[left]\n",
    "                cnt[nums[left]] -= 1\n",
    "                left += 1\n",
    "\n",
    "            cnt[x] += 1\n",
    "            sum_ += x\n",
    "            ans = max(ans, sum_)\n",
    "            #print(left,right,ans)\n",
    "\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumUniqueSubarray(self, nums: List[int]) -> int:\n",
    "        ans = 0\n",
    "        n = len(nums)\n",
    "        first =  [-1]*(max(nums)+1)\n",
    "        count = 0\n",
    "        l = 0\n",
    "        for i in range(n):\n",
    "            count += nums[i]\n",
    "            if first[nums[i]]!=-1:\n",
    "                while l<=first[nums[i]]:\n",
    "                    count -= nums[l]\n",
    "                    first [nums[l]] =-1\n",
    "                    l+=1\n",
    "            first[nums[i ]] = i\n",
    "            if count > ans :\n",
    "                ans =count\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumUniqueSubarray(self, nums: List[int]) -> int:\n",
    "        sum_, max_sum, hasmap = 0, 0, {}\n",
    "\n",
    "        start = 0\n",
    "        for end in range(len(nums)):\n",
    "            tail = nums[end]\n",
    "            sum_ += tail\n",
    "            hasmap[tail] = hasmap.get(tail, 0) + 1\n",
    "            if end - start + 1 == len(hasmap):\n",
    "                max_sum = max(max_sum, sum_)\n",
    "\n",
    "            while end - start + 1 > len(hasmap):\n",
    "                head = nums[start]\n",
    "                hasmap[head] -= 1\n",
    "                if hasmap[head] == 0:\n",
    "                    del hasmap[head]\n",
    "                sum_ -= nums[start]\n",
    "                start += 1\n",
    "        return max_sum"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        sz = len(nums)\n",
    "        if sz < 2:\n",
    "            return 0\n",
    "        nums.sort()\n",
    "        result = 0\n",
    "        for i in range(sz - 1):\n",
    "            a = nums[i]\n",
    "            b = nums[i + 1]\n",
    "            c = b - a\n",
    "            result = max(result, c)\n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "class Solution(object):\n",
    "    def maximumGap(self, nums):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        # 获取数字的个数\n",
    "        count = len(nums)\n",
    "        # 如果小于两个数字，则根据题意返回0\n",
    "        if count < 2:\n",
    "            return 0\n",
    "        # 确定所有数的范围，寻找最值和最小值\n",
    "        maxnum, minnum = max(nums), min(nums)\n",
    "        # 计算数与数之间的平均距离（例如有10个数字，则一共有9个区间，平均的区间差为（最大值-最小值/9）向上取整）\n",
    "        gap = math.ceil((maxnum - minnum) / (count - 1))\n",
    "        # 如果gap\n",
    "        if gap == 0:\n",
    "            return 0\n",
    "        size = int((maxnum - minnum) / gap) + 1\n",
    "        bucketmin, bucketmax = [sys.maxsize] * size, [-sys.maxsize] * size\n",
    "        for i in range(count):\n",
    "            index = int((nums[i] - minnum) / gap)\n",
    "            bucketmin[index] = min(bucketmin[index], nums[i])\n",
    "            bucketmax[index] = max(bucketmax[index], nums[i])\n",
    "        premax, maxgap = bucketmax[0], 0\n",
    "        for i in range(1, size):\n",
    "            if bucketmin[i] != sys.maxsize:\n",
    "                maxgap = max(maxgap, bucketmin[i] - premax)\n",
    "                premax = bucketmax[i]\n",
    "        return maxgap\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import math\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        n = len(nums)\n",
    "        if n < 2:\n",
    "            return 0\n",
    "        buckets = [None for i in range(n)]\n",
    "        min_value = min(nums)\n",
    "        max_value = max(nums)\n",
    "        r = (max_value - min_value + 1) / n\n",
    "        for num in nums:\n",
    "            id_bucket = math.ceil((num - min_value + 1) / r) - 1\n",
    "            if buckets[id_bucket] is None:\n",
    "                buckets[id_bucket] = (num, num)\n",
    "            else:\n",
    "                buckets[id_bucket] = (min(num, buckets[id_bucket][0]), max(num, buckets[id_bucket][1]))\n",
    "        last_bucket = None\n",
    "        max_gap = 0\n",
    "        for bucket in buckets:\n",
    "            if bucket == None:\n",
    "                continue\n",
    "            if last_bucket != None:\n",
    "                max_gap = max(max_gap, bucket[0] - last_bucket[1])\n",
    "            last_bucket = bucket\n",
    "        return max_gap\n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        n = len(nums)\n",
    "        if n <=1:\n",
    "            return 0\n",
    "        maxN = minN = nums[0]\n",
    "        for num in nums:\n",
    "            if num < minN:\n",
    "                minN = num\n",
    "            if num > maxN:\n",
    "                maxN = num\n",
    "        if maxN - minN <=1:\n",
    "            return maxN - minN\n",
    "        b = (maxN - minN) / n\n",
    "        k = int((maxN - minN) / b) + 1\n",
    "        bucket_mins = [None]*k\n",
    "        bucket_maxs = [None]*k\n",
    "        for num in nums:\n",
    "            index = int((num - minN) / b)\n",
    "            if bucket_maxs[index] == None:\n",
    "                bucket_maxs[index] = num\n",
    "                bucket_mins[index] = num\n",
    "            else:\n",
    "                if bucket_maxs[index] < num:\n",
    "                    bucket_maxs[index] = num\n",
    "                if bucket_mins[index] > num:\n",
    "                    bucket_mins[index] = num\n",
    "        preMax = None\n",
    "        max_gap = 0\n",
    "        for i in range (k):\n",
    "            if bucket_mins[i]!=None:\n",
    "                if preMax != None and bucket_mins[i] - preMax > max_gap:\n",
    "                    max_gap = bucket_mins[i] - preMax\n",
    "                preMax = bucket_maxs[i]\n",
    "        return max_gap"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        ln = len(nums)\n",
    "        if ln < 2:\n",
    "            return 0\n",
    "        maxn = max(nums)\n",
    "        minn = min(nums)\n",
    "        nums = set(nums)\n",
    "        ln = len(nums)\n",
    "        if ln < 2:\n",
    "            return 0\n",
    "        gap = (maxn - minn)//(ln-1)\n",
    "        if gap==0:\n",
    "            return 0\n",
    "        pcs = (maxn-minn)//gap\n",
    "        buckets = [[] for x in range(pcs+1)]\n",
    "        for x in nums:\n",
    "            index = (x-minn)//gap\n",
    "            if len(buckets[index]) == 0:\n",
    "                buckets[index].append(x)\n",
    "            elif len(buckets[index]) == 1:\n",
    "                buckets[index].append(x)\n",
    "                buckets[index].sort()\n",
    "            else:\n",
    "                buckets[index][0] = min(buckets[index][0],x)\n",
    "                buckets[index][1] = max(buckets[index][1],x)\n",
    "        i = 0\n",
    "        while len(buckets[i])==0:\n",
    "            i+=1\n",
    "        g = 0\n",
    "        last = buckets[i][-1]\n",
    "        while i<len(buckets):\n",
    "            if len(buckets[i]) == 0:\n",
    "                i += 1\n",
    "                continue\n",
    "            g = max(g,buckets[i][0]-last)\n",
    "            last = buckets[i][-1]\n",
    "            i+=1\n",
    "        return g"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    \"\"\"\n",
    "    :type nums: List[int]\n",
    "    :rtype: int\n",
    "    \"\"\"\n",
    "    def maximumGap(self, nums):\n",
    "        l = len(nums)\n",
    "        if l < 2:\n",
    "            return 0        \n",
    "        polar = nums[0]\n",
    "        lgaps = []\n",
    "        rgaps = []\n",
    "        for num in nums[1:]:\n",
    "            gap = num - polar\n",
    "            if gap > 0:\n",
    "                rgaps.append(gap)\n",
    "            elif gap < 0:\n",
    "                lgaps.append(-gap)\n",
    "        results = []\n",
    "        if len(rgaps) > 0:\n",
    "            results.append(min(rgaps))\n",
    "            results.append(self.maximumGap(rgaps))\n",
    "        if len(lgaps) > 0:\n",
    "            results.append(min(lgaps))\n",
    "            results.append(self.maximumGap(lgaps))\n",
    "        return max(results) if len(results) > 0 else 0\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    \"\"\"\n",
    "    :type nums: List[int]\n",
    "    :rtype: int\n",
    "    \"\"\"\n",
    "    def maximumGap(self, nums):\n",
    "        l = len(nums)\n",
    "        if l < 2:\n",
    "            return 0\n",
    "        if l == 2:\n",
    "            return nums[1] - nums[0] if nums[1] > nums[0] else nums[0] - nums[1]\n",
    "        polar = nums[0]\n",
    "        left = []\n",
    "        right = []\n",
    "        lgaps = []\n",
    "        rgaps = []\n",
    "        for num in nums:\n",
    "            gap = num - polar\n",
    "            if gap > 0:\n",
    "                right.append(num)\n",
    "                rgaps.append(gap)\n",
    "            elif gap < 0:\n",
    "                left.append(num)\n",
    "                lgaps.append(-gap)\n",
    "        options = [self.maximumGap(left), self.maximumGap(right)]\n",
    "        if len(lgaps) > 0:\n",
    "            options.append(min(lgaps))\n",
    "        if len(rgaps) > 0:\n",
    "            options.append(min(rgaps))\n",
    "        return max(options)\n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    \"\"\"\n",
    "    :type nums: List[int]\n",
    "    :rtype: int\n",
    "    \"\"\"\n",
    "    def maximumGap(self, nums):\n",
    "        l = len(nums)\n",
    "        if l < 2:\n",
    "            return 0\n",
    "        if l == 2:\n",
    "            return nums[1] - nums[0] if nums[1] > nums[0] else nums[0] - nums[1]\n",
    "        polar = nums[0]\n",
    "        left = []\n",
    "        right = []\n",
    "        lgaps = []\n",
    "        rgaps = []\n",
    "        for num in nums:\n",
    "            gap = num - polar\n",
    "            if gap > 0:\n",
    "                right.append(num)\n",
    "                rgaps.append(gap)\n",
    "            elif gap < 0:\n",
    "                left.append(num)\n",
    "                lgaps.append(-gap)\n",
    "        options = []\n",
    "        if len(lgaps) > 0:\n",
    "            options.append(min(lgaps))\n",
    "            options.append(self.maximumGap(left))\n",
    "        if len(rgaps) > 0:\n",
    "            options.append(min(rgaps))\n",
    "            options.append(self.maximumGap(right))\n",
    "        return 0 if len(options) == 0  else max(options)\n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        if len(nums) < 2:\n",
    "            return 0\n",
    "\n",
    "        numDic = {}\n",
    "        uniqNums = []\n",
    "        mini, maxi = nums[0], nums[0]\n",
    "        for n in nums:\n",
    "            if n in numDic:\n",
    "                continue\n",
    "            uniqNums.append(n)\n",
    "            numDic[n] = 1\n",
    "            if n < mini:\n",
    "                mini = n\n",
    "            if n > maxi:\n",
    "                maxi = n\n",
    "\n",
    "        numCount = len(uniqNums)\n",
    "        if numCount < 2:\n",
    "            return 0\n",
    "        elif numCount == 2:\n",
    "            return abs(uniqNums[1] - uniqNums[0])\n",
    "        elif numCount == (maxi - mini + 1):\n",
    "            return 1\n",
    "\n",
    "        ranges = {}\n",
    "        rangeWidth = (maxi - mini + 1) // (numCount + 1)\n",
    "        for num in uniqNums:\n",
    "            i = (num - mini) // rangeWidth \n",
    "            if i >= numCount:\n",
    "                ranges[numCount] = 1\n",
    "            else:\n",
    "                ranges[i] = 1\n",
    "\n",
    "        widestEmptyRange = []\n",
    "        maxWidth, i = 0, 0\n",
    "        while i < numCount:\n",
    "            if i in ranges:\n",
    "                i += 1\n",
    "                continue\n",
    "            j = i + 1\n",
    "            width = 1\n",
    "            while j < numCount + 1:\n",
    "                if j not in ranges:\n",
    "                    width += 1\n",
    "                    j += 1\n",
    "                else:\n",
    "                    break\n",
    "            if width > maxWidth:\n",
    "                widestEmptyRange = [[i, j - 1]]\n",
    "                maxWidth = width\n",
    "            elif width == maxWidth:\n",
    "                widestEmptyRange.append([i, j - 1])\n",
    "            i = j\n",
    "\n",
    "        gap = 0\n",
    "        for r in widestEmptyRange:\n",
    "            offsetLow = mini + r[0] * rangeWidth\n",
    "            offsetHigh = mini + (r[1] + 1) * rangeWidth - 1\n",
    "            while True:\n",
    "                if offsetLow in numDic and offsetHigh in numDic:\n",
    "                    break\n",
    "                else:\n",
    "                    if offsetLow not in numDic:\n",
    "                        offsetLow -= 1\n",
    "                    if offsetHigh not in numDic:\n",
    "                        offsetHigh += 1\n",
    "                \n",
    "            if offsetHigh - offsetLow > gap:\n",
    "                gap = offsetHigh - offsetLow\n",
    "\n",
    "        return gap\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import math\n",
    "\n",
    "class Solution:\n",
    "    \"\"\"\n",
    "    :type nums: List[int]\n",
    "    :rtype: int\n",
    "    \"\"\"\n",
    "    def maximumGap(self, nums):\n",
    "        l = len(nums)\n",
    "        if l < 2:\n",
    "            return 0\n",
    "        n1 = self.createNode(nums[0])\n",
    "        n2 = self.createNode(nums[1])\n",
    "        if n1['v'] > n2['v']:\n",
    "            n1['l'] = n2\n",
    "            n2['r'] = n1\n",
    "            self.queue = [n1]\n",
    "            self.leftBoundary = n2\n",
    "            self.rightBoundary = n1\n",
    "        else:\n",
    "            n1['r'] = n2\n",
    "            n2['l'] = n1\n",
    "            self.queue = [n2]\n",
    "            self.leftBoundary = n1\n",
    "            self.rightBoundary = n2\n",
    "        self.pending = []\n",
    "        for num in nums[2:]:\n",
    "            if self.updateQueueIfNodeInMaxGap(num):\n",
    "                self.rebuildQueue()\n",
    "        right = self.queue.pop()\n",
    "        left = right['l']\n",
    "        return right['v'] - left['v']\n",
    "\n",
    "    def updateQueueIfNodeInMaxGap(self, num):\n",
    "        if num > self.rightBoundary['v']:\n",
    "            node = self.createNode(num, self.rightBoundary)\n",
    "            self.rightBoundary['r'] = node\n",
    "            self.rightBoundary = node\n",
    "            self.addNode(node)\n",
    "            return False\n",
    "        elif num < self.leftBoundary['v']:\n",
    "            node = self.createNode(num, None, self.leftBoundary)\n",
    "            self.leftBoundary['l'] = node\n",
    "            self.addNode(self.leftBoundary)\n",
    "            self.leftBoundary = node\n",
    "            return False\n",
    "        \n",
    "        right = self.queue.pop()\n",
    "        left = right['l']\n",
    "        if num > left['v'] and num < right['v']:\n",
    "            node = self.createNode(num, left, right)\n",
    "            right['l'] = left['r'] = node\n",
    "            self.addNode(right)\n",
    "            self.addNode(node)\n",
    "            return True\n",
    "        else:\n",
    "            self.pending.append(num)\n",
    "            self.queue.append(right)\n",
    "            return False\n",
    "    \n",
    "    def addNode(self, node):\n",
    "        head = 0\n",
    "        tail = len(self.queue) - 1\n",
    "        if tail == -1 or self.compareNode(node, self.queue[tail]) >= 0:\n",
    "            self.queue.append(node)\n",
    "            return\n",
    "        elif self.compareNode(node, self.queue[head]) <= 0:\n",
    "            self.queue = [node] + self.queue\n",
    "            return\n",
    "        while tail - head > 1:\n",
    "            cursor = math.ceil((tail - head) / 2) + head\n",
    "            if self.compareNode(node, self.queue[cursor]) >= 0:\n",
    "                head = cursor\n",
    "            else:\n",
    "                tail = cursor\n",
    "        self.queue = self.queue[:tail] + [node] + self.queue[tail:]\n",
    "\n",
    "    def rebuildQueue(self):\n",
    "        pending = self.pending\n",
    "        self.pending = []\n",
    "        rebuild = False\n",
    "        for num in pending:\n",
    "            if self.updateQueueIfNodeInMaxGap(num):\n",
    "                rebuild = True\n",
    "        if rebuild:\n",
    "            self.rebuildQueue()\n",
    "        \n",
    "    def compareNode(self, a, b):\n",
    "        ga = a['v'] - a['l']['v']\n",
    "        gb = b['v'] - b['l']['v']\n",
    "        if ga > gb:\n",
    "            return 1\n",
    "        elif ga < gb:\n",
    "            return -1\n",
    "        else:\n",
    "            return 0\n",
    "\n",
    "    def printQueue(self):\n",
    "        queue = []\n",
    "        for node in self.queue:\n",
    "            queue.append(node['v'])\n",
    "        print(queue)\n",
    "\n",
    "    def findAnswer(self, ans, input):\n",
    "        for v in input:\n",
    "            if (v + ans) in input :\n",
    "                print(v, v + ans)\n",
    "            if (v - ans) in input:\n",
    "                print(v, v - ans)\n",
    "\n",
    "    def createNode(self, val, left = None, right = None):\n",
    "        return {\n",
    "            'v': val,\n",
    "            'l': left,\n",
    "            'r': right,\n",
    "        }\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: 'list[int]') -> 'int':\n",
    "        if len(nums) < 2:\n",
    "            return 0\n",
    "\n",
    "        nums.sort()\n",
    "        for i in range(len(nums)-1,-1,-1):\n",
    "            nums[i] = nums[i] - nums[i-1]\n",
    "\n",
    "        max = nums[1]\n",
    "        for i in range(1,len(nums)):\n",
    "            if nums[i] > max:\n",
    "                max = nums[i]\n",
    "\n",
    "        return max\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        print(nums)\n",
    "        l=len(nums)-1\n",
    "        if len(nums)<2:\n",
    "            return 0\n",
    "        while l>0:\n",
    "            nums[l]-=nums[l-1]\n",
    "            l-=1\n",
    "        #for i in range(1,len(nums)):\n",
    "        #    nums[i]=nums[i]-nums[i-1]\n",
    "        print(nums[1:])\n",
    "        return max(nums[1:])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        size = len(nums)\n",
    "        if size < 2: return 0\n",
    "        nums.sort()\n",
    "        res = 0\n",
    "        for i in range(1, size):\n",
    "            if nums[i] - nums[i - 1] > res: res = nums[i] - nums[i - 1]\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        if len(nums) < 2:\n",
    "            return 0\n",
    "        jianju = 0\n",
    "        nums.sort()\n",
    "        for i in range(len(nums)-1):\n",
    "            jianju = max(nums[i+1]-nums[i], jianju)\n",
    "        return jianju"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        if n<2: return 0\n",
    "        maxnum,minnum = max(nums),min(nums)\n",
    "        if maxnum==minnum: return 0\n",
    "        bucket_len = max(1,(maxnum-minnum)//(n-1))\n",
    "        bucket_num = (maxnum-minnum)//bucket_len+1\n",
    "        buckets = [[] for _ in range(bucket_num)]\n",
    "           \n",
    "        for num in nums:\n",
    "            idx = (num-minnum)//bucket_len\n",
    "            buckets[idx].append(num)\n",
    "\n",
    "        res = 0\n",
    "        pre = float('inf')\n",
    "        for i in range(bucket_num):\n",
    "            if buckets[i]:\n",
    "                res =  max(res,min(buckets[i])-pre)\n",
    "                pre = max(buckets[i])\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        res = 0\n",
    "        if len(nums) < 2:\n",
    "            return res\n",
    "        sort_nums = sorted(nums)\n",
    "        for cur in range(len(sort_nums) - 1):\n",
    "            next = cur + 1\n",
    "            res = max(res, sort_nums[next] - sort_nums[cur])\n",
    "\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        if len(nums)<2: return 0\n",
    "        nums.sort()\n",
    "        res = 0\n",
    "        for i in range(1, len(nums)):\n",
    "            res = max(res, nums[i]-nums[i-1])\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        # 基排序\n",
    "        digits=10\n",
    "        length=len(nums)\n",
    "        if length <=1:\n",
    "            return 0\n",
    "        minValue= min(nums)\n",
    "        nums=[num-minValue for num in nums]\n",
    "        buckets=[[] for _ in range(10)]\n",
    "\n",
    "        for digit in range(1,11):\n",
    "            # print('digit',digit)\n",
    "            for num in nums:\n",
    "                digitNum = self.getDigits(num,digit)\n",
    "                # print('digitNum',digitNum)\n",
    "                buckets[digitNum].append(num)\n",
    "            cnt=0\n",
    "            for i in range(10):\n",
    "                while buckets[i] != []:\n",
    "                    number=buckets[i].pop(0)\n",
    "                    nums[cnt]=number\n",
    "                    cnt +=1\n",
    "\n",
    "            # print('nums',nums)\n",
    "\n",
    "        interval=0\n",
    "        for i in range(length-1):\n",
    "            if nums[i+1]-nums[i] >interval:\n",
    "                interval = nums[i+1]-nums[i]\n",
    "        return interval\n",
    "\n",
    "\n",
    "    def getDigits(self,num,i):\n",
    "        return (num- (num//(10**i)) * 10**i)//10**(i-1)\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums ) -> int:\n",
    "\n",
    "        if len(nums)<2:\n",
    "            return 0\n",
    "\n",
    "        min_val = float('inf')\n",
    "        max_val = float('-inf')\n",
    "\n",
    "        for num in nums:\n",
    "            min_val = min(min_val,num)\n",
    "            max_val = max(max_val,num)\n",
    "\n",
    "        d = int((max_val-min_val)/(len(nums)-1))\n",
    "        if d == 0:\n",
    "            if max_val-min_val == 0:\n",
    "                return 0\n",
    "            else:\n",
    "                d=1\n",
    "\n",
    "\n",
    "        bucket_num = int((max_val-min_val)/d)+1\n",
    "\n",
    "        buckets = [[float('inf'),float('-inf')] for i in range(bucket_num)]\n",
    "\n",
    "        for num in nums:\n",
    "            bucket_id = (num-min_val)//d\n",
    "\n",
    "            buckets[bucket_id][0] = min(buckets[bucket_id][0],num)\n",
    "            buckets[bucket_id][1] = max(buckets[bucket_id][1],num)\n",
    "\n",
    "        i = 1\n",
    "        ans = 0\n",
    "        last_max = buckets[0][1]\n",
    "        while i<len(buckets):\n",
    "\n",
    "            while i<len(buckets) and buckets[i][0] == float('inf'):\n",
    "                i+=1\n",
    "\n",
    "            if i<len(buckets):\n",
    "                ans = max(buckets[i][0]-last_max,ans)\n",
    "                last_max = buckets[i][1]\n",
    "                i+=1\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def radixSort(self,nums):\n",
    "        arr=[[i,n] for i,n in enumerate(nums)]\n",
    "\n",
    "        while True:\n",
    "            buckets=[[] for i in range(10)]\n",
    "            \n",
    "            count_0=0\n",
    "            for ind,ele in enumerate(arr):\n",
    "                n=ele[1]\n",
    "                base=n%10\n",
    "                n=n//10\n",
    "                ele[1]=n\n",
    "                if n==0 :\n",
    "                    count_0+=1\n",
    "                buckets[base].append(ele)\n",
    "            \n",
    "            tmp=[]\n",
    "            for b in buckets:\n",
    "                tmp.extend(b)\n",
    "            arr=tmp\n",
    "\n",
    "            if count_0 == len(nums):\n",
    "                break\n",
    "        sorted_indx= [ind for ind,n in arr]\n",
    "        sorted_nums = [nums[ind] for ind in sorted_indx] \n",
    "        return sorted_nums\n",
    "    \n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        nums= self.radixSort(nums)\n",
    "\n",
    "        max_gap=0\n",
    "        for i in range(1,len(nums)):\n",
    "            if nums[i]-nums[i-1]>max_gap:\n",
    "                max_gap = nums[i]-nums[i-1]\n",
    "        return max_gap"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        if len(nums) < 2: return 0\n",
    "        if len(nums) == 2: return abs(nums[0] - nums[1])\n",
    "\n",
    "        # low16 = lambda x: x % 65536\n",
    "        # high16 = lambda x: x // 65536\n",
    "        \n",
    "        cnt = [0] * 65536\n",
    "        tmp = [0] * len(nums)\n",
    "        for x in nums: cnt[x % 65536] += 1\n",
    "        for i in range(1, 65536): cnt[i] += cnt[i - 1]\n",
    "        target = nums[::-1]\n",
    "        for x in target:\n",
    "            data = x % 65536\n",
    "            cnt[data] -= 1\n",
    "            tmp[cnt[data]] = x\n",
    "\n",
    "        cnt = [0] * 65536\n",
    "        for x in tmp: \n",
    "            cnt[x // 65536] += 1\n",
    "        for i in range(1, 65536): cnt[i] += cnt[i - 1]\n",
    "        target = tmp[::-1]\n",
    "        for x in target:\n",
    "            data = x // 65536\n",
    "            cnt[data] -= 1\n",
    "            nums[cnt[data]] = x\n",
    "\n",
    "        maxDist  = -1\n",
    "        for i in range(1, len(nums)):\n",
    "            maxDist = max(maxDist, nums[i]- nums[i-1])\n",
    "        return maxDist"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        if len(nums) < 2: return 0\n",
    "        if len(nums) == 2: return abs(nums[0] - nums[1])\n",
    "\n",
    "        # low16 = lambda x: x % 65536\n",
    "        # high16 = lambda x: x // 65536\n",
    "        \n",
    "        cnt = [0] * 65536\n",
    "        tmp = [0] * len(nums)\n",
    "        for x in nums: cnt[x % 65536] += 1\n",
    "        for i in range(1, 65536): cnt[i] += cnt[i - 1]\n",
    "        target = nums[::-1]\n",
    "        for x in target:\n",
    "            data = x % 65536\n",
    "            cnt[data] -= 1\n",
    "            tmp[cnt[data]] = x\n",
    "\n",
    "        cnt = [0] * 65536\n",
    "        for x in tmp: \n",
    "            cnt[x // 65536] += 1\n",
    "        for i in range(1, 65536): cnt[i] += cnt[i - 1]\n",
    "        target = tmp[::-1]\n",
    "        for x in target:\n",
    "            data = x // 65536\n",
    "            cnt[data] -= 1\n",
    "            nums[cnt[data]] = x\n",
    "\n",
    "        maxDist  = -1\n",
    "        for i in range(1, len(nums)):\n",
    "            if maxDist > nums[i] - nums[i - 1]: continue\n",
    "            maxDist = nums[i]- nums[i-1]\n",
    "        return maxDist"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "from functools import reduce\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        if len(nums)<2:\n",
    "            return 0\n",
    "        nums = list(map(lambda x:list(str(x).rjust(32,'0')),nums))\n",
    "\n",
    "        def sorted_(nums,idx):\n",
    "            bu = [[] for _ in range(10)]\n",
    "            for i in range(len(nums)):\n",
    "                bu[ord(nums[i][idx])-ord('0')].append(i)\n",
    "            res = []\n",
    "            for i in range(10):\n",
    "                for j in range(len(bu[i])):\n",
    "                    res.append(nums[bu[i][j]])\n",
    "            return res\n",
    "        for i in range(31,-1,-1):\n",
    "            nums = sorted_(nums, i)\n",
    "\n",
    "        new_nums = []\n",
    "        for t in nums:\n",
    "            new_nums.append(reduce(lambda x,y:int(x)*10+int(y),t))\n",
    "        res = new_nums[1]-new_nums[0]\n",
    "        for i in range(1,len(new_nums)):\n",
    "            res = max(res,new_nums[i]-new_nums[i-1])\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def bruteForce(self, nums):\n",
    "        nums.sort()\n",
    "        maxGap = 0\n",
    "        for i in range(len(nums) - 1):\n",
    "            maxGap = max(maxGap, nums[i + 1] - nums[i])\n",
    "        return maxGap\n",
    "\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        '''\n",
    "        input length 1? -> output 0\n",
    "        input length 0? -> output 0\n",
    "        '''\n",
    "        if len(nums) < 2:\n",
    "            return 0\n",
    "        numsRange = max(nums) - min(nums) + 1\n",
    "        if numsRange > 1000000:\n",
    "            return self.bruteForce(nums)\n",
    "        offset = min(nums)\n",
    "        existNums = [False for i in range(numsRange)]\n",
    "        for i in range(len(nums)):\n",
    "            existNums[nums[i] - offset] = True\n",
    "        maxDistance = 0\n",
    "        lastExistNumIndex = 0\n",
    "        for i in range(numsRange):\n",
    "            if existNums[i]:\n",
    "                maxDistance = max(i - lastExistNumIndex, maxDistance)\n",
    "                lastExistNumIndex = i\n",
    "        return maxDistance"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        n=len(nums)\n",
    "        if (n<2):\n",
    "            return 0\n",
    "        maxnum=max(nums)+1\n",
    "        if n<25 or maxnum>99999900:\n",
    "            nums.sort()\n",
    "            diff=[nums[i]-nums[i-1] for i in range(1,n)]\n",
    "            return max(diff)\n",
    "        sortplace=[0]*maxnum\n",
    "        for i in nums:\n",
    "            if sortplace[i]!=1:\n",
    "                sortplace[i]=1\n",
    "        nsorted=[i for i in range(maxnum) if sortplace[i]!=0]\n",
    "        n2=len(nsorted)\n",
    "        diff=[nsorted[i]-nsorted[i-1] for i in range(1,n2)]\n",
    "        return max(diff)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        if len(nums) < 2: return 0\n",
    "        heapq.heapify(nums)\n",
    "        ans = 0\n",
    "        pre = heapq.heappop(nums)\n",
    "        while nums:\n",
    "            cur = heapq.heappop(nums)\n",
    "            ans = max(cur - pre, ans)\n",
    "            pre = cur\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        if len(nums) < 2:\n",
    "            return 0\n",
    "        heapify(nums)\n",
    "        former = heappop(nums)\n",
    "        max_gap = 0\n",
    "        while nums:\n",
    "            latter = heappop(nums)\n",
    "            max_gap = max(max_gap, latter-former)\n",
    "            former = latter\n",
    "        return max_gap"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "\n",
    "        pre = None\n",
    "\n",
    "        heapq.heapify(nums)\n",
    "        res = 0\n",
    "        length = len(nums)\n",
    "        for _ in range(length):\n",
    "            q = heapq.heappop(nums)\n",
    "            if pre is not None:\n",
    "                res = max(res, q - pre)\n",
    "            pre = q\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        t = sorted(nums)\n",
    "        return max(y-x for x, y in zip(t, t[1:])) if len(nums) >= 2 else 0 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "maxD = 10**9\r\n",
    "class Solution:\r\n",
    "    def traverse(self, nums, left , right):\r\n",
    "        key = nums[left]\r\n",
    "        bl = kl = left\r\n",
    "        left+=1\r\n",
    "        minL = maxD\r\n",
    "        minR = maxD\r\n",
    "        while left<right:\r\n",
    "            d = key-nums[left]\r\n",
    "            if d > 0:\r\n",
    "                minL = min(minL, key-nums[left])\r\n",
    "                nums[kl], nums[left] = nums[left], nums[kl+1]\r\n",
    "                kl+=1\r\n",
    "            elif d == 0:\r\n",
    "                right-=1\r\n",
    "                nums[right], nums[left] = nums[left], nums[right]\r\n",
    "                left-=1\r\n",
    "            else:\r\n",
    "                minR = min(minR, -d)\r\n",
    "            left+=1\r\n",
    "        minL = max(minL if minL != maxD else 0, self.traverse(nums, bl, kl) if kl>bl+1 else 0)\r\n",
    "        minR = max(minR if minR != maxD else 0, self.traverse(nums, kl+1, right) if right>kl+2 else 0)\r\n",
    "        return max(minL, minR)\r\n",
    "    def maximumGap(self, nums: List[int]) -> int:\r\n",
    "        if len(nums) <= 1: return 0\r\n",
    "        return self.traverse(nums, 0, len(nums))\r\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        # 方式1，用基数排序，在最后一轮的时候计算最大间距值\n",
    "        if len(nums) < 2:\n",
    "            return 0\n",
    "        res = 0\n",
    "        import math\n",
    "        i, it = 0, int(math.log(max(nums), 10))\n",
    "        while i <= it:\n",
    "            # 生成10个桶\n",
    "            buckets = [[] for _ in range(10)]\n",
    "            for num in nums:\n",
    "                # 分别从个位，十位，百位....开始取余计算\n",
    "                digit = (num // 10 ** i) % 10\n",
    "                # 如果是最后一轮，则计算间距差\n",
    "                if i == it and buckets[digit]:\n",
    "                    res = max(res, num - buckets[digit][-1])\n",
    "                    # 分桶\n",
    "                buckets[digit].append(num)\n",
    "\n",
    "            # 分桶完成，将数据依次取出\n",
    "            nums.clear()\n",
    "            for buc in buckets:\n",
    "                # 最后一轮计算桶边界差\n",
    "                if i == it and nums and buc:\n",
    "                    res = max(res, buc[0] - nums[-1])\n",
    "                # 将数据重新写回nums\n",
    "                nums.extend(buc)\n",
    "            i += 1\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution(object):\n",
    "    def maximumGap(self, nums):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        if len(nums)<2:\n",
    "            return 0\n",
    "        nums.sort()\n",
    "        if nums[0]==nums[-1]:\n",
    "            return 0\n",
    "        for i in range(len(nums)-1,-1,-1):\n",
    "            if i==0:\n",
    "                continue\n",
    "            nums[i]-=nums[i-1]\n",
    "        return max(nums[1:])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        if len(nums) <2:\n",
    "            return 0\n",
    "        nums.sort()\n",
    "        cha=0\n",
    "        for i in range(len(nums)-1):\n",
    "            print(nums[i])\n",
    "            cha=max(cha,abs(nums[i]-nums[i+1]))\n",
    "        return cha"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        nums.sort()\n",
    "        n = len(nums)\n",
    "        if n < 2:\n",
    "            return 0\n",
    "\n",
    "        res = 0\n",
    "        for i in range(1, n):\n",
    "            res = max(res, abs(nums[i-1]-nums[i]))\n",
    "\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        if not nums:  # 处理输入为空的情况\n",
    "            return 0\n",
    "        nums.sort()\n",
    "        res = []\n",
    "        p = 0\n",
    "        while p < len(nums)-1:\n",
    "            q = p+1\n",
    "            res.append(nums[q]-nums[p])\n",
    "            p += 1\n",
    "        if not res:  # 处理无间距的情况\n",
    "            return 0\n",
    "        return max(res)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "            if len(nums)<2:\n",
    "                return 0\n",
    "            else:\n",
    "                nums.sort()\n",
    "                a=[]\n",
    "                for i in range(len(nums)):\n",
    "                    if i+1<len(nums):\n",
    "                        a.append(nums[i+1]-nums[i])\n",
    "                return (max(a))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        \n",
    "        maxn = max(nums)\n",
    "        minn = min(nums)\n",
    "        n = len(nums)\n",
    "        if n==1:\n",
    "            return 0 \n",
    "\n",
    "        d = (maxn-minn)//(n-1)\n",
    "        if d==0:\n",
    "            d = 1 \n",
    "        x = ((maxn-minn)//d )+1\n",
    "        max_bucket = [float(\"-inf\")]*x\n",
    "        min_bucket = [float(\"inf\")]*x \n",
    "\n",
    "        for y in nums:\n",
    "            index = (y-minn)//d \n",
    "            if y>max_bucket[index]:\n",
    "                max_bucket[index] = y \n",
    "            if y<min_bucket[index]:\n",
    "                min_bucket[index] = y \n",
    "\n",
    "        #print(max_bucket)\n",
    "        #print(min_bucket)\n",
    "        pre_max = float(\"inf\")\n",
    "        pre_min = float(\"-inf\")\n",
    "        ans = 0\n",
    "        for i in range(x):\n",
    "            if max_bucket[i]==float(\"-inf\"):\n",
    "                continue\n",
    "            cur_max = max_bucket[i]\n",
    "            cur_min = min_bucket[i]\n",
    "            ans = max(ans,cur_max-cur_min)\n",
    "            ans = max(ans,cur_min-pre_max)\n",
    "            pre_max,pre_min = cur_max,cur_min\n",
    "        return ans \n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        if len(nums)<2: return 0\n",
    "        if len(nums)==2: return abs(nums[0]-nums[1])\n",
    "\n",
    "        minnum = min(nums)\n",
    "        maxnum = max(nums)\n",
    "        if maxnum==minnum: return 0\n",
    "\n",
    "        length = len(nums)+1 #桶的大小\n",
    "        record_max = [-1]*length #记录当前桶的最大值\n",
    "        record_min = [10**6]*length #记录当前桶的最大值\n",
    "        hasnum = [False]*length #记录当前桶是否有数值\n",
    "        for i in range(len(nums)):\n",
    "            idx = int((nums[i]-minnum)*len(nums)/(maxnum-minnum)) #桶的索引\n",
    "            if not hasnum[idx]:\n",
    "                record_max[idx] = nums[i]\n",
    "                record_min[idx] = nums[i]\n",
    "                hasnum[idx] = True\n",
    "            else:\n",
    "                record_max[idx] = max(record_max[idx], nums[i])\n",
    "                record_min[idx] = min(record_min[idx], nums[i])\n",
    "                \n",
    "        res = 0\n",
    "        tmp = record_max[0]\n",
    "        for i in range(1, length):\n",
    "            if hasnum[i]:\n",
    "                res = max(res, record_min[i]-tmp)\n",
    "                tmp = record_max[i]\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        if n < 2:\n",
    "            return 0\n",
    "        \n",
    "        checkList = defaultdict()\n",
    "        buffer = [-1 for _ in range(n)]\n",
    "        maxVal = max(nums)\n",
    "        limit = 1\n",
    "\n",
    "        while maxVal >= limit:\n",
    "            count = [0 for _ in range(10)]\n",
    "            for num in nums:\n",
    "                digit = (num // limit) % 10\n",
    "                count[digit] += 1\n",
    "            \n",
    "            for i in range(1, 10):\n",
    "                count[i] += count[i - 1]\n",
    "\n",
    "            for i in range(n - 1, -1, -1):\n",
    "                digit = (nums[i] // limit) % 10\n",
    "                buffer[count[digit] - 1] = nums[i]\n",
    "                count[digit] -= 1\n",
    "            \n",
    "            nums = buffer[:]\n",
    "            limit *= 10\n",
    "\n",
    "        print(nums)\n",
    "        ans = 0\n",
    "        for i in range(1, n):\n",
    "            ans = max(ans, nums[i] - nums[i - 1])\n",
    "        \n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        if len(nums) < 2:\n",
    "            return 0\n",
    "        n = len(str(max(nums)))\n",
    "        for k in range(n):\n",
    "            bucket_list = [[] for _ in range(10)]\n",
    "            for i in nums:\n",
    "                bucket_list[i // (10 ** k) % 10].append(i)\n",
    "            nums = [j for i in bucket_list for j in i]\n",
    "        res = 0\n",
    "        for i in range(1, len(nums)):\n",
    "            res = max(nums[i] - nums[i-1], res)\n",
    "        return res\n",
    "        # if len(nums) < 2:\n",
    "        #     return 0\n",
    "        # n = len(nums)\n",
    "        # min_val = min(nums)\n",
    "        # max_val = max(nums)\n",
    "        # d = max(1, (max_val - min_val) // (n - 1))\n",
    "        # num_buckets = (max_val - min_val) // d + 1\n",
    "        # buckets = [[] for _ in range(num_buckets)]\n",
    "        # for i in nums:\n",
    "        #     buckets_index = (i - min_val) // d\n",
    "        #     tmp = buckets[buckets_index]\n",
    "        #     if len(tmp) == 0:\n",
    "        #         tmp = [i, i]\n",
    "        #     else:\n",
    "        #         tmp = [min(tmp[0], i), max(tmp[1], i)]\n",
    "        #     buckets[buckets_index] = tmp\n",
    "        \n",
    "        # res = 0\n",
    "        # pre = -1\n",
    "        # for i in range(len(buckets)):\n",
    "        #     if len(buckets[i]) > 0:\n",
    "        #         if pre >= 0:\n",
    "        #             res = max(res, buckets[i][0] - buckets[pre][1])\n",
    "        #         pre = i\n",
    "        # return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        if len(nums)<2: return 0\n",
    "        if len(nums)==2: return abs(nums[0]-nums[1])\n",
    "\n",
    "        minnum = min(nums)\n",
    "        maxnum = max(nums)\n",
    "        if maxnum==minnum: return 0\n",
    "\n",
    "        lenth = len(nums)+1 #桶的数量\n",
    "        record_max = [-1]*lenth #记录当前桶的最大值\n",
    "        record_min = [10**6]*lenth #记录当前桶的最大值\n",
    "        hasnum = [False]*lenth #记录当前桶是否有数值\n",
    "        for i in range(len(nums)):\n",
    "            idx = int((nums[i]-minnum)*len(nums)/(maxnum-minnum)) #桶的索引\n",
    "            if not hasnum[idx]:\n",
    "                record_max[idx] = nums[i]\n",
    "                record_min[idx] = nums[i]\n",
    "                hasnum[idx] = True\n",
    "            else:\n",
    "                record_max[idx] = max(record_max[idx], nums[i])\n",
    "                record_min[idx] = min(record_min[idx], nums[i])\n",
    "\n",
    "        print(record_max, record_min, hasnum)\n",
    "        \n",
    "        #  这里计算每个桶之间的差值的最大值，即为最终的最大值\n",
    "        res = 0\n",
    "        tmp = record_max[0] # 第0个桶的最大值\n",
    "        for i in range(1,lenth):\n",
    "            if hasnum[i]:\n",
    "                res = max(res, record_min[i]-tmp) # 计算res与两个桶之间的差值，取最大值；\n",
    "                tmp = record_max[i]\n",
    "        \n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        if len(nums)<2:\n",
    "            return 0\n",
    "        if len(nums)==2:\n",
    "            return abs(nums[1]-nums[0])\n",
    "\n",
    "        minimum = min(nums)\n",
    "        maximum = max(nums)\n",
    "        if minimum==maximum:\n",
    "            return 0\n",
    "\n",
    "        N = len(nums)-1\n",
    "        interval = (maximum - minimum)/N\n",
    "\n",
    "        minimums = [float('inf')]*N\n",
    "        maximums = [float('-inf')]*N\n",
    "        \n",
    "        for x in nums:\n",
    "            index = int((x-minimum)/interval)\n",
    "            if index==N:\n",
    "                index=N-1\n",
    "            minimums[index] = min(minimums[index], x)\n",
    "            maximums[index] = max(maximums[index], x)\n",
    "        \n",
    "        minimums = [x for x in minimums if x != float('inf')]\n",
    "        maximums = [x for x in maximums if x != float('-inf')]\n",
    "\n",
    "        result = 0\n",
    "        for i in range(len(minimums)-1):\n",
    "            result = max(result, minimums[i+1]-maximums[i])\n",
    "        \n",
    "        return result\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        def quickSort(nums):\n",
    "            n=len(nums)\n",
    "            if n<=1:\n",
    "                return nums\n",
    "            pivot_index=random.randint(0, n-1)\n",
    "            pivot=nums[pivot_index]\n",
    "            left_part=[x for x in nums if x < pivot]\n",
    "            mid_part=[x for x in nums if x == pivot]\n",
    "            right_part=[x for x in nums if x > pivot]\n",
    "            return quickSort(left_part)+mid_part+quickSort(right_part)\n",
    "\n",
    "        if len(nums)<2:\n",
    "            return 0\n",
    "        nums=quickSort(nums)\n",
    "        nums1=nums[1:]\n",
    "        nums2=nums[:-1]\n",
    "        results=[]\n",
    "        \n",
    "        for v1,v2 in zip(nums1,nums2):\n",
    "            results.append(v1-v2)\n",
    "        return max(results)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        min_num, max_num = min(nums), max(nums)\n",
    "        bucket_size = max(1, (max_num - min_num) // len(nums) -1)\n",
    "        bucket_num = (max_num - min_num) // bucket_size + 1\n",
    "\n",
    "        buckets = [[None, None] for _ in range(bucket_num)]\n",
    "\n",
    "        for num in nums:\n",
    "            idx  = (num-min_num) // bucket_size\n",
    "            if buckets[idx][0] is None:\n",
    "                buckets[idx][0], buckets[idx][1] = num, num\n",
    "            else:\n",
    "                buckets[idx][0] = min(num, buckets[idx][0])\n",
    "                buckets[idx][1] = max(num, buckets[idx][1])\n",
    "        \n",
    "        max_gap, prev_max = 0, min_num\n",
    "        for i in range(bucket_num):\n",
    "            if buckets[i][0] is not None:\n",
    "                max_gap = max(max_gap, buckets[i][0] - prev_max)\n",
    "                prev_max = buckets[i][1]\n",
    "\n",
    "        return max_gap"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        if n < 2:\n",
    "            return 0\n",
    "        minVal = min(nums)\n",
    "        maxVal = max(nums)\n",
    "        d = max(1, (maxVal - minVal) // (n - 1))\n",
    "        bucketSize = (maxVal - minVal) // d + 1\n",
    "\n",
    "        # 使用 (-1, -1) 初始化 bucket，表示该桶为空\n",
    "        bucket = [[-1, -1] for _ in range(bucketSize)]\n",
    "        \n",
    "        for num in nums:\n",
    "            idx = (num - minVal) // d\n",
    "            if bucket[idx][0] == -1:\n",
    "                bucket[idx][0] = bucket[idx][1] = num\n",
    "            else:\n",
    "                bucket[idx][0] = min(bucket[idx][0], num)\n",
    "                bucket[idx][1] = max(bucket[idx][1], num)\n",
    "\n",
    "        ret = 0\n",
    "        prev = -1\n",
    "        for i in range(bucketSize):\n",
    "            if bucket[i][0] == -1:\n",
    "                continue\n",
    "            if prev != -1:\n",
    "                ret = max(ret, bucket[i][0] - bucket[prev][1])\n",
    "            prev = i\n",
    "            \n",
    "        return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        if len(nums) < 2: return 0\n",
    "        \n",
    "        # 一些初始化\n",
    "        max_ = max(nums)\n",
    "        min_ = min(nums)\n",
    "        max_gap = 0\n",
    "        \n",
    "        each_bucket_len = max(1,(max_-min_) // (len(nums)-1))\n",
    "        buckets =[[] for _ in range((max_-min_) // each_bucket_len + 1)]\n",
    "        \n",
    "        # 把数字放入桶中\n",
    "        for i in range(len(nums)):\n",
    "            loc = (nums[i] - min_) // each_bucket_len\n",
    "            buckets[loc].append(nums[i])\n",
    "        \n",
    "        # 遍历桶更新答案\n",
    "        prev_max = float('inf')\n",
    "        for i in range(len(buckets)):\n",
    "            if buckets[i] and prev_max != float('inf'):\n",
    "                max_gap = max(max_gap, min(buckets[i])-prev_max)\n",
    "            \n",
    "            if buckets[i]:\n",
    "                prev_max = max(buckets[i])\n",
    "                \n",
    "        return max_gap"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        if len(nums) < 2:\n",
    "            return 0 \n",
    "        \n",
    "        max_ = max(nums)\n",
    "        min_ = min(nums)\n",
    "        max_gap = 0 \n",
    "        print(max(1, (max_ - min_)),len(nums),12)\n",
    "        each_bucket_len = max(1, (max_ - min_) // (len(nums) - 1))\n",
    "        buckets =[[] for _ in range((max_ - min_) // each_bucket_len + 1)]\n",
    "\n",
    "        for i in range(len(nums)):\n",
    "            loc = (nums[i] - min_) // each_bucket_len\n",
    "            buckets[loc].append(nums[i])\n",
    "\n",
    "        prev_max = float('inf')\n",
    "        for i in range(len(buckets)):\n",
    "            if buckets[i] and prev_max != float('inf'):\n",
    "                max_gap = max(max_gap, min(buckets[i])-prev_max)\n",
    "            \n",
    "            if buckets[i]:\n",
    "                prev_max = max(buckets[i])\n",
    "        return max_gap\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        if len(nums) < 2: return 0\n",
    "\n",
    "        min_ = min(nums)\n",
    "        max_ = max(nums)\n",
    "\n",
    "        bottle_size = max(1, (max_ - min_)//(len(nums) - 1))\n",
    "        bottles = [[] for _ in range((max_ - min_)//bottle_size + 1)]\n",
    "\n",
    "        for i in nums:\n",
    "            bottles[(i - min_)//bottle_size].append(i)\n",
    "\n",
    "        last = max(bottles[0])\n",
    "        res = 0\n",
    "        for b in bottles[1:]:\n",
    "            if b:\n",
    "                res = max(res, min(b) - last) \n",
    "                last = max(b)\n",
    "\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def bucket_sort(self, arr):\n",
    "        # 创建空桶\n",
    "        num_buckets = len(arr)\n",
    "        buckets = [[] for _ in range(num_buckets)]\n",
    "\n",
    "        # 将元素分配到桶中\n",
    "        max_val = max(arr)\n",
    "        for num in arr:\n",
    "            index = int(num * num_buckets / (max_val + 1))\n",
    "            buckets[index].append(num)\n",
    "\n",
    "        # 对每个桶内的元素进行排序（这里使用插入排序）\n",
    "        for i in range(num_buckets):\n",
    "            buckets[i].sort()\n",
    "\n",
    "        # 合并排序后的桶\n",
    "        result = []\n",
    "        for bucket in buckets:\n",
    "            result.extend(bucket)\n",
    "\n",
    "        return result\n",
    "\n",
    "\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        sorted_nums = self.bucket_sort(nums)\n",
    "        max_gap = 0\n",
    "        for i in range(len(sorted_nums)-1):\n",
    "            max_gap = max(max_gap, sorted_nums[i+1]-sorted_nums[i])\n",
    "        return max_gap"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        n=len(nums)\n",
    "        if n<2:\n",
    "            return 0\n",
    "        \n",
    "        maxNum = max(nums)\n",
    "        minNum = min(nums)\n",
    "        max_gap=0\n",
    "\n",
    "        each_bucket_len=max(1,(maxNum-minNum)//(len(nums)-1))\n",
    "        buckets =[[] for _ in range((maxNum-minNum) // each_bucket_len + 1)]\n",
    "\n",
    "\n",
    "        for i in range(len(nums)):\n",
    "            loc = (nums[i] - minNum) // each_bucket_len\n",
    "            buckets[loc].append(nums[i])\n",
    "        print(buckets)\n",
    "\n",
    "        prev_max=float(\"inf\")\n",
    "        for i in range(len(buckets)):\n",
    "            if buckets[i] and prev_max!=float(\"inf\"):\n",
    "                max_gap=max(max_gap, min(buckets[i])-prev_max)\n",
    "            \n",
    "            if buckets[i]:\n",
    "                prev_max=max(buckets[i])\n",
    "        return max_gap\n",
    "\n",
    "\n",
    "     "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        # def maximumGap(nums):\n",
    "        n = len(nums)\n",
    "        if n < 2:\n",
    "            return 0\n",
    "\n",
    "        # 计算桶的数量和区间大小\n",
    "        min_val, max_val = min(nums), max(nums)\n",
    "        gap = max(1, (max_val - min_val) // (n - 1))\n",
    "        num_buckets = (max_val - min_val) // gap + 1\n",
    "\n",
    "        # 初始化桶和记录每个桶的最大值和最小值\n",
    "        buckets = [[] for _ in range(num_buckets)]\n",
    "        for num in nums:\n",
    "            idx = (num - min_val) // gap\n",
    "            buckets[idx].append(num)\n",
    "\n",
    "        bucket_min = [min(b) for b in buckets if b]\n",
    "        bucket_max = [max(b) for b in buckets if b]\n",
    "\n",
    "        # 计算相邻非空桶之间的最大差值\n",
    "        max_gap = 0\n",
    "        for i in range(1, len(bucket_min)):\n",
    "            max_gap = max(max_gap, bucket_min[i] - bucket_max[i-1])\n",
    "        \n",
    "        return max_gap\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "###桶排序，因为最大间隔>=(max-min)//(len(num1)-1),否则max=min+(len-1)*间隔<min+(max-min)/(len-1)*(len-1)=max矛盾，想设计桶使得桶内元素间隔<max-min//(len-1),那么最大间隔只产生在桶之间。假设分桶原则为index=num//b,同一个桶的元素满足i<=index<i+1,即i*b=<num<(i+1)*b,所以想让桶内元素间隔<b<(max-min)//(len-1),b=(max-min)/len满足条件，因为分桶index>0,元素可能小于0，所以减去一个最小值。因此分桶规则为(i-min)*len/(max-min)，min在0桶，max在len桶，桶个数为len+1\n",
    "         \n",
    "        bucket=[[] for _ in range(len(nums)+1)]\n",
    "        min1=min(nums)\n",
    "        max1=max(nums)\n",
    "        maxbuc=[-float('inf')]*(len(nums)+1)\n",
    "        minbuc=[float('inf')]*(len(nums)+1)\n",
    "        hasnum=[False]*(len(nums)+1)\n",
    "        if len(nums)<=2:\n",
    "            return max1-min1\n",
    "        if max1==min1:\n",
    "            return 0\n",
    "        for n in nums:\n",
    "            index=(n-min1)*len(nums)//(max1-min1)\n",
    "            bucket[index].append(n)\n",
    "            maxbuc[index]=max(maxbuc[index],n)\n",
    "            minbuc[index]=min(minbuc[index],n)\n",
    "            hasnum[index]=True\n",
    "        maxdis=-float('inf')\n",
    "        #print(maxbuc,minbuc)\n",
    "        maxnum=maxbuc[0]###记录不为空的桶的最大值，间隔为不为空桶的最小值-前一个桶最大值,第0个桶一定有数字min1,hasnum[0]=True\n",
    "        for i in range(1,len(nums)+1):\n",
    "            if hasnum[i]:\n",
    "                maxdis=max(maxdis,minbuc[i]-maxnum)\n",
    "                maxnum=maxbuc[i]\n",
    "        return maxdis\n",
    "\n",
    "            \n",
    "\n",
    "       "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        n=len(nums)\n",
    "        if n==1: return 0\n",
    "        maxn=max(nums);minn=min(nums)\n",
    "        k=max(1,(maxn-minn)//(n-1))\n",
    "        b=(maxn-minn)//k+1\n",
    "        bucket=[[] for _ in range(b)]\n",
    "        for i in range(n):\n",
    "            loc=(nums[i]-minn)//k\n",
    "            bucket[loc].append(nums[i])\n",
    "        res=0\n",
    "        for i in range(1,b):\n",
    "            if not bucket[i]: bucket[i]=[max(bucket[i-1])]\n",
    "            res=max(min(bucket[i])-max(bucket[i-1]),res)\n",
    "        print(bucket)\n",
    "        return res\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    import math\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        n=len(nums)\n",
    "        if n<2:\n",
    "            return 0\n",
    "        max_num=max(nums)\n",
    "        min_num=min(nums)\n",
    "        d=max(1, (max_num-min_num)//(n-1))\n",
    "        m=(max_num-min_num)//d +1\n",
    "        buckets=[(-math.inf, math.inf, False)]*m\n",
    "        for num in nums:\n",
    "            idx=(num-min_num)//d\n",
    "            if buckets[idx][2]:\n",
    "                buckets[idx]=(min(buckets[idx][0], num), max(buckets[idx][1], num), True)\n",
    "            else:\n",
    "                buckets[idx]=(num, num, True)\n",
    "        ans=0\n",
    "        print(buckets)\n",
    "        for i in range(m-1):\n",
    "            if buckets[i][2]:\n",
    "                j=i+1\n",
    "                while j < m and buckets[j][2]==False:\n",
    "                    j+=1\n",
    "                if buckets[j][2]:\n",
    "                    ans=max(ans, buckets[j][0]-buckets[i][1])\n",
    "        return ans\n",
    "\n",
    "\n",
    "\n",
    "            \n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        nums=list(set(nums))\n",
    "        n=len(nums)\n",
    "        if n==1:\n",
    "            return 0\n",
    "        mn=min(nums)\n",
    "        mx=max(nums)\n",
    "        if n==2:\n",
    "            return mx-mn\n",
    "        if mx==mn:\n",
    "            return 0\n",
    "        m=(mx-mn+1)//(n-1)\n",
    "        buckets=[[1145141919810,0] for _ in range((mx-mn+m)//m)]\n",
    "        for e in nums:\n",
    "            i=(e-mn)//m \n",
    "            buckets[i][0]=min(buckets[i][0],e)\n",
    "            buckets[i][1]=max(buckets[i][1],e)\n",
    "            # print(i,buckets)\n",
    "        ans=0\n",
    "        i=0\n",
    "        while i < len(buckets)-1:\n",
    "            j=i+1\n",
    "            while buckets[j][0]==1145141919810:\n",
    "                j+=1\n",
    "            ans=max(ans,buckets[j][0]-buckets[i][1])\n",
    "            i=j\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        n=len(nums)\n",
    "        if n<2:\n",
    "            return 0\n",
    "        maxval,minval=max(nums),min(nums)\n",
    "        d=max(1,(maxval-minval)//(n-1))\n",
    "        bucketsize=(maxval-minval)//d+1\n",
    "        bucket=[[float('inf'),float('-inf')] for _ in range(bucketsize)]\n",
    "        for num in nums:\n",
    "            idx=(num-minval)//d\n",
    "            bucket[idx][0]=min(bucket[idx][0],num)\n",
    "            bucket[idx][1]=max(bucket[idx][1],num)\n",
    "        ans,prev=0,-1\n",
    "        for i in range(bucketsize):\n",
    "            if bucket[i][0]==float('inf') or bucket[i][1]==float('-inf'):\n",
    "                continue\n",
    "            if prev!=-1:\n",
    "                ans=max(ans,bucket[i][0]-bucket[prev][1])\n",
    "            prev=i\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    import math\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        n=len(nums)\n",
    "        if n<2:\n",
    "            return 0\n",
    "        max_num=max(nums)\n",
    "        min_num=min(nums)\n",
    "        d=max(1, (max_num-min_num)//(n-1))\n",
    "        m=(max_num-min_num)//d +1\n",
    "        buckets=[[math.inf, -math.inf, False] for _ in range(m)]\n",
    "        for num in nums:\n",
    "            idx=(num-min_num)//d\n",
    "            buckets[idx][2]=True\n",
    "            buckets[idx][0]=min(buckets[idx][0], num)\n",
    "            buckets[idx][1]=max(buckets[idx][1], num)\n",
    "        ans=0\n",
    "        last=min_num\n",
    "        for i in range(m):\n",
    "            if buckets[i][2]:\n",
    "                ans=max(ans, buckets[i][0]-last)\n",
    "                last=buckets[i][1]\n",
    "        return ans\n",
    "\n",
    "\n",
    "\n",
    "            \n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        if n == 1:\n",
    "            return 0\n",
    "        maxNum, minNum = nums[0], nums[0]\n",
    "        for num in nums:\n",
    "            if num > maxNum:\n",
    "                maxNum = num\n",
    "            if num < minNum:\n",
    "                minNum = num\n",
    "        bucketGap = (maxNum - minNum) // (n - 1)\n",
    "        if bucketGap == 0:\n",
    "            bucketGap = 1\n",
    "        bucketMin = {}\n",
    "        bucketMax = {}\n",
    "        for num in nums:\n",
    "            bucketId = (num - minNum) // bucketGap\n",
    "            if bucketId not in bucketMin.keys():\n",
    "                bucketMin[bucketId] = num\n",
    "                bucketMax[bucketId] = num\n",
    "            else:\n",
    "                if num < bucketMin[bucketId]:\n",
    "                    bucketMin[bucketId] = num\n",
    "                if num > bucketMax[bucketId]:\n",
    "                    bucketMax[bucketId] = num\n",
    "        lastMax = bucketMax[0]\n",
    "        ans = 0\n",
    "        for bucketId in range(n):\n",
    "            if bucketId in bucketMin.keys():\n",
    "                if bucketMax[bucketId] - bucketMin[bucketId] > ans:\n",
    "                    ans = bucketMax[bucketId] - bucketMin[bucketId]\n",
    "                if bucketId > 0:\n",
    "                    if bucketMin[bucketId] - lastMax > ans:\n",
    "                        ans = bucketMin[bucketId] - lastMax\n",
    "                    lastMax = bucketMax[bucketId]\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        if n < 2: \n",
    "            return 0\n",
    "        max_num = max(nums)\n",
    "        min_num = min(nums)\n",
    "\n",
    "        # n个数分到n-1个桶, 不放最大最小值, gap可以设置得更小一点\n",
    "        gap = math.ceil((max_num - min_num) / (n-1))\n",
    "\n",
    "        # 每个bucket维护最小值和最大值\n",
    "        bucket = [[float('inf'), -float('inf')] for i in range(n-1)]\n",
    "        for i in range(n):\n",
    "            if nums[i] == max_num or nums[i] == min_num:\n",
    "                continue\n",
    "            loc = (nums[i] - min_num) // gap\n",
    "            bucket[loc][0] = min(bucket[loc][0], nums[i])\n",
    "            bucket[loc][1] = max(bucket[loc][1], nums[i])\n",
    "        \n",
    "        premin = min_num\n",
    "        res = -float('inf')\n",
    "        for x,y in bucket:\n",
    "            if x == float('inf'):\n",
    "                continue\n",
    "            res = max(res, x - premin)\n",
    "            premin = y\n",
    "        \n",
    "        print(premin, max_num)\n",
    "        res = max(res, max_num - premin)\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGap(self, nums: List[int]) -> int:\n",
    "        n_len = len(nums)\n",
    "        if n_len < 2: return 0\n",
    "        \n",
    "        min_val, max_val = min(nums), max(nums)\n",
    "        d = max(1, (max_val - min_val) // (n_len - 1))\n",
    "        b_len = (max_val - min_val) // d + 1\n",
    "        \n",
    "        buckets = [[float('inf'), float('-inf')] for _ in range(b_len)]\n",
    "        for n in nums:\n",
    "            bk_i = (n - min_val) // d\n",
    "            if n < buckets[bk_i][0]: buckets[bk_i][0] = n\n",
    "            if n > buckets[bk_i][1]: buckets[bk_i][1] = n\n",
    "        \n",
    "        rnt, pre = 0, min_val\n",
    "        for i in range(b_len):\n",
    "            if buckets[i][0] == float('inf'): continue\n",
    "            \n",
    "            rnt = max(rnt, buckets[i][0]-pre)\n",
    "            pre = buckets[i][1]\n",
    "        \n",
    "        return rnt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        n = len(statements)\n",
    "        ans = 0\n",
    "        for mask in range(1, 1 << n):\n",
    "            def check() -> bool:\n",
    "                for i in range(n):\n",
    "                    for j in range(n):\n",
    "                        if i == j:\n",
    "                            continue\n",
    "                        if statements[i][j] == 0:\n",
    "                            if mask & (1 << i) and mask & (1 << j):\n",
    "                                return False\n",
    "                        elif statements[i][j] == 1:\n",
    "                            if mask & (1 << i) and not mask & (1 << j):\n",
    "                                return False\n",
    "                return True\n",
    "            \n",
    "            if check():\n",
    "                ans = max(ans, bin(mask).count(\"1\"))\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        def check(i: int) -> int:\n",
    "            cnt = 0  # i 中好人个数\n",
    "            for j, row in enumerate(statements):  # 枚举 i 中的好人 j\n",
    "                if (i >> j) & 1:\n",
    "                    if any(st < 2 and st != (i >> k) & 1 for k, st in enumerate(row)):\n",
    "                        return 0  # 好人 j 的某个陈述 st 与实际情况矛盾\n",
    "                    cnt += 1\n",
    "            return cnt\n",
    "\n",
    "        return max(check(i) for i in range(1, 1 << len(statements)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        def check(i):\n",
    "            cnt = 0\n",
    "            for j, row in enumerate(statements):\n",
    "                if (i >> j) & 1:\n",
    "                    if any(st < 2 and st != (i >> k) & 1 for k, st in enumerate(row)):\n",
    "                        return 0\n",
    "                    cnt += 1\n",
    "            return cnt\n",
    "        return max(check(i) for i in range(1, 1 << len(statements)))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        n = len(statements)\n",
    "        ans = 0\n",
    "        for i in range(1,1 << n):\n",
    "            cishu = 0\n",
    "            flag = True\n",
    "            for j, state in enumerate(statements):\n",
    "                #if i & (1 << j):\n",
    "                if (i >> j) & 1:\n",
    "                    cishu += 1\n",
    "                    for k, v in enumerate(state):\n",
    "                        #if v < 2 and i & (1 << k) != v:\n",
    "                        if v < 2 and (i >> k) & 1 != v:\n",
    "                            flag = False\n",
    "                            break\n",
    "                if not flag:\n",
    "                    break\n",
    "            if flag:\n",
    "                ans = max(ans, cishu)\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        a = statements\n",
    "        n = len(a)\n",
    "        def check(st):\n",
    "            for i in range(n):\n",
    "                if st >> i & 1:\n",
    "                    for j, x in enumerate(a[i]):\n",
    "                        if x == 0 and st >> j & 1 == 1:\n",
    "                            return False\n",
    "                        if x == 1 and st >> j & 1 == 0:\n",
    "                            return False\n",
    "            return True\n",
    "        ans = 0\n",
    "        for i in range(1 << n):\n",
    "            if check(i):\n",
    "                ans = max(ans, i.bit_count())\n",
    "        return ans\n",
    "                    \n",
    "                \n",
    "                    \n",
    "                \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        n = len(statements)\n",
    "\n",
    "        def check(mask):\n",
    "            for i in range(n):\n",
    "                if not mask >> i & 1:\n",
    "                    continue\n",
    "                for j in range(n):\n",
    "                    if j == i:\n",
    "                        continue\n",
    "                    if (statements[i][j] == 0 and mask >> j & 1) or (statements[i][j] == 1 and not mask >> j & 1):\n",
    "                        return False\n",
    "            return True\n",
    "\n",
    "        ans = 0\n",
    "        for mask in range(1, 1<<n):\n",
    "            if check(mask):\n",
    "                ans = max(ans, mask.bit_count())\n",
    "        return ans\n",
    "                   "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        N = len(statements)\n",
    "        goods = [[] for _ in range(N)]\n",
    "        bads = [[] for _ in range(N)]\n",
    "        for i in range(N):\n",
    "            for j in range(N):\n",
    "                if statements[i][j] == 1:\n",
    "                    goods[i].append(j)\n",
    "                elif statements[i][j] == 0:\n",
    "                    bads[i].append(j)\n",
    "        ans = 0\n",
    "        for state in range((1 << N) - 1, -1, -1):\n",
    "            if state.bit_count() <= ans:\n",
    "                continue\n",
    "            success = True\n",
    "            for i in range(N):\n",
    "                if (state >> i) & 1:\n",
    "                    for j in goods[i]:\n",
    "                        if (state >> j) & 1 == 0:\n",
    "                            success = False\n",
    "                            break\n",
    "                    for j in bads[i]:\n",
    "                        if (state >> j) & 1 == 1:\n",
    "                            success = False\n",
    "                            break\n",
    "                if not success:\n",
    "                    break\n",
    "            if success and state.bit_count() > ans:\n",
    "                ans = state.bit_count()\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from typing import List\n",
    "from itertools import combinations\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        n = len(statements)\n",
    "        \n",
    "        def check(good_set):\n",
    "            for i in good_set:\n",
    "                for j in range(n):\n",
    "                    if j == i:\n",
    "                        continue\n",
    "                    if statements[i][j] == 0 and j in good_set:\n",
    "                        return False\n",
    "                    if statements[i][j] == 1 and j not in good_set:\n",
    "                        return False\n",
    "            return True\n",
    "\n",
    "        max_good = 0\n",
    "        for size in range(1, n + 1):\n",
    "            for good_set in combinations(range(n), size):\n",
    "                if check(good_set):\n",
    "                    max_good = max(max_good, size)\n",
    "        \n",
    "        return max_good"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        n=len(statements)\n",
    "        \n",
    "        def check(mask):\n",
    "            for i in range(n):\n",
    "                for j in range(n):\n",
    "                    if i==j :\n",
    "                        continue\n",
    "                    \n",
    "                    if statements[i][j]==0 and mask&(1<<i)==(1<<i) and mask&(1<<j)==(1<<j):\n",
    "                        return False\n",
    "                    if statements[i][j]==1 and mask&(1<<i)==(1<<i)  and mask&(1<<j)!=(1<<j):\n",
    "                        return False\n",
    "\n",
    "            return True\n",
    "\n",
    "        mx=0\n",
    "        for i in range(1,1<<n):\n",
    "            if check(i)==True:\n",
    "         \n",
    "                mx=max(mx,bin(i).count(\"1\"))\n",
    "                print(bin(i))\n",
    "        return mx\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        n = len(statements)\n",
    "        good = [0] * n\n",
    "        bad = [0] * n\n",
    "        for i, statement in enumerate(statements):\n",
    "            g = 0\n",
    "            b = (1 << n) - 1\n",
    "            for j, x in enumerate(statement):\n",
    "                if x == 1:\n",
    "                    g |= 1 << j\n",
    "                elif x == 0:\n",
    "                    b &= ~(1 << j)\n",
    "            good[i], bad[i] = g, b\n",
    "\n",
    "        ans = 0\n",
    "        for i in range(1, 1 << n):\n",
    "            vaild = True\n",
    "            for j in range(n):\n",
    "                if 1 << j & i:\n",
    "                    if i & good[j] != good[j] or i | bad[j] != bad[j]:\n",
    "                        vaild = False\n",
    "                        break\n",
    "            if vaild:\n",
    "                ans = max(ans, i.bit_count())\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        n = len(statements)\n",
    "        judge_lst = [2] * n\n",
    "        num = func1(judge_lst,statements)\n",
    "        return num\n",
    "\t\n",
    "def func1(judge_lst,statements):\n",
    "    n = len(judge_lst)\n",
    "    if n == 0:\n",
    "        return 0\n",
    "\n",
    "    if judge_lst[-1] == 1:\n",
    "        return 1 + func1(judge_lst[:-1],statements)\n",
    "    if judge_lst[-1] == 0:\n",
    "        return func1(judge_lst[:-1],statements)\n",
    "\t\n",
    "    num1 = num2 = -15\n",
    "    # 假设是好人\n",
    "    lst1 = judge_lst[:]\n",
    "    n = len(lst1) - 1\n",
    "    if check_good(lst1,statements, n):\n",
    "        num1 = 1 + func1(lst1[:-1],statements)\n",
    "\t\t\n",
    "    # 假设是坏人\n",
    "    lst2 = judge_lst[:]\n",
    "    n = len(lst2) - 1\n",
    "    if check_bad(lst2,statements, n):\n",
    "        num2 = func1(lst2[:-1],statements)\n",
    "\t\n",
    "    # 如果都矛盾\n",
    "    return max(num1,num2)\n",
    "\n",
    "def check_good(lst1, statements,n):\n",
    "    tmp = statements[n][:n]\n",
    "    # 我说别人\n",
    "    for i, v in enumerate(tmp):\n",
    "        if v == 1 and lst1[i] == 0:\n",
    "            return False\n",
    "        if v == 0 and lst1[i] == 1:\n",
    "            return False\n",
    "        if v == 1:\n",
    "            lst1[i] = 1\n",
    "            if not check_good(lst1,statements,i):\n",
    "                return False\n",
    "\n",
    "        if v == 0:\n",
    "            lst1[i] = 0\n",
    "            if not check_bad(lst1,statements,i):\n",
    "                return False\n",
    "\n",
    "    # 别人说我\n",
    "    for j in range(n):\n",
    "        if statements[j][n] == 0:\n",
    "            if lst1[j] == 1:\n",
    "                return False\n",
    "            lst1[j] = 0\n",
    "            if not check_bad(lst1,statements,j):\n",
    "                return False\n",
    "    return True\n",
    "\n",
    "\n",
    "def check_bad(lst2, statements,n):\n",
    "    # 别人说我\n",
    "    for j in range(n):\n",
    "        if statements[j][n] == 1:  # 我是坏人，但有人说我是好人，那么他是坏人\n",
    "            if lst2[j] == 1:\n",
    "                return False\n",
    "            lst2[j] = 0\n",
    "            if not check_bad(lst2,statements,j):\n",
    "                return False\n",
    "    return True\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        n = len(statements)\n",
    "        def check(i):\n",
    "            cnt = 0\n",
    "            for j, row in enumerate(statements):\n",
    "                if i >> j & 1:\n",
    "                    for k, st in enumerate(row):\n",
    "                        if st < 2 and st != ((i >> k) & 1): \n",
    "                            #print(i, j, k, st, bin(i)[2:])\n",
    "                            return 0\n",
    "                    cnt += 1\n",
    "            return cnt\n",
    "        return max(check(i) for i in range(1, (1 << n)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        \"\"\"\n",
    "        有 n 个人，每个人可能是好人，也可能是坏人，\n",
    "        因此这 n 个人的好坏有 2^n 种情况。\n",
    "\n",
    "        二进制枚举好人（一共 2^n 种情况），\n",
    "        然后根据好人的陈述来判断合法性：\n",
    "\n",
    "        因为好人只说真话，那么：\n",
    "            - 好人对好人的陈述只能是 1 或 2，即不能是 0\n",
    "            - 好人对坏人的陈述只能是 0 或 2，即不能是 \n",
    "        \"\"\"\n",
    "\n",
    "        def check(good: List[int], bad: List[int]) -> bool:\n",
    "            # 1. 检查好人对好人的陈述\n",
    "            # 好人对好人的陈述只能是 1 或 2，即不能是 0\n",
    "            for i in good:\n",
    "                for j in good:\n",
    "                    if i != j and statements[i][j] == 0:\n",
    "                        return False\n",
    "            \n",
    "            # 2. 检查好人对坏人的陈述\n",
    "            # 好人对坏人的陈述只能是 0 或 2，即不能是 1\n",
    "            for i in good:\n",
    "                for j in bad:\n",
    "                    if statements[i][j] == 1:\n",
    "                        return False\n",
    "\n",
    "            return True\n",
    "\n",
    "\n",
    "        n = len(statements)\n",
    "        res = 0\n",
    "        # 二进制枚举好人\n",
    "        for mask in range(1 << n):\n",
    "            # good: 好人\n",
    "            #  bad: 坏人\n",
    "            good, bad = [], []\n",
    "            \n",
    "            for i in range(n):\n",
    "                if mask & 1:\n",
    "                    good.append(i)\n",
    "                else:\n",
    "                    bad.append(i)\n",
    "                mask >>= 1\n",
    "\n",
    "            if check(good, bad):\n",
    "                res = max(res, len(good))\n",
    "\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        n = len(statements)\n",
    "\n",
    "        def check(state):\n",
    "            g = set()\n",
    "            for i in range(n):\n",
    "                if state & 1 << i:\n",
    "                    g.add(i)\n",
    "            res = set()\n",
    "            for i in g:\n",
    "                for j in range(n):\n",
    "                    if statements[i][j] == 0 and j in g:\n",
    "                        return False\n",
    "                    elif statements[i][j] == 1 and j not in g:\n",
    "                        return False\n",
    "\n",
    "            return True\n",
    "            \n",
    "        ans = 0\n",
    "        for i in range(1, 1 << n):\n",
    "            if check(i):\n",
    "                ans = max(ans, i.bit_count())\n",
    "\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from math import *\n",
    "from queue import PriorityQueue,Queue\n",
    "from typing import *\n",
    "from heapq import *\n",
    "from functools import lru_cache\n",
    "from string import *\n",
    "# by hangpengjie\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        n = len(statements)\n",
    "        res = 0\n",
    "        def check(mask:int)->bool:\n",
    "            for i in range(n):\n",
    "                if (1 << i) & mask:\n",
    "                    for j in range(n):\n",
    "                        if statements[i][j] < 2:\n",
    "                            if (mask >> j) & 1 ^ statements[i][j]:\n",
    "                                return False\n",
    "            return True\n",
    "        for i in range(1<<n):\n",
    "            if check(i):\n",
    "                res = max(res,i.bit_count())\n",
    "\n",
    "        \n",
    "    \n",
    "        return res\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        def check(i: int) -> int:\n",
    "            cnt = 0  # i 中好人个数\n",
    "            for j, row in enumerate(statements):  # 枚举 i 中的好人 j\n",
    "                if (i >> j) & 1:\n",
    "                    if any(st < 2 and st != (i >> k) & 1 for k, st in enumerate(row)):\n",
    "                        return 0  # 好人 j 的某个陈述 st 与实际情况矛盾\n",
    "                    cnt += 1\n",
    "            return cnt\n",
    "\n",
    "        return max(check(i) for i in range(1, 1 << len(statements)))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        n = len(statements)\n",
    "        ans = 0\n",
    "\n",
    "        for i in range(1, 1 << n):\n",
    "            score = 0\n",
    "            flag = True\n",
    "            for j in range(n):\n",
    "                if (i >> j) & 1:\n",
    "                    score += 1\n",
    "                    if all(statements[j][k] == (i >> k) & 1 for k in range(n) if statements[j][k] < 2):\n",
    "                        continue\n",
    "                    else:\n",
    "                        flag = False\n",
    "                        break\n",
    "            if flag:\n",
    "                ans = max(ans, score)\n",
    "        return ans\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        def check(i: int) -> int:\n",
    "            cnt = 0  # i 中好人个数\n",
    "            for j, row in enumerate(statements):  # 枚举 i 中的好人 j\n",
    "                if (i >> j) & 1:\n",
    "                    if any(st < 2 and st != (i >> k) & 1 for k, st in enumerate(row)):\n",
    "                        return 0  # 好人 j 的某个陈述 st 与实际情况矛盾\n",
    "                    cnt += 1\n",
    "            return cnt\n",
    "\n",
    "        return max(check(i) for i in range(1, 1 << len(statements)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def __init__(self): \n",
    "        self.max_total = 0\n",
    "        \n",
    "    def backtracking(self, statements, player, good, bad): \n",
    "        # base case \n",
    "        if player == len(statements): \n",
    "            self.max_total = max(len(good), self.max_total)\n",
    "            return \n",
    "        \n",
    "        # backtracking \n",
    "        for i in range(player, len(statements)): \n",
    "            # prune \n",
    "            if i in bad:    \n",
    "                continue \n",
    "                \n",
    "            new_good = [j for j in range(len(statements[i])) if statements[i][j] == 1]\n",
    "            new_good.append(i)\n",
    "            new_bad = [j for j in range(len(statements[i])) if statements[i][j] == 0]\n",
    "                        \n",
    "            new_good = [x for x in new_good if x not in good]\n",
    "            new_bad = [x for x in new_bad if x not in bad]\n",
    "            \n",
    "            if len(set(good+new_good).intersection(set(bad+new_bad))) > 0:\n",
    "                # prune \n",
    "                pass \n",
    "            else: \n",
    "                self.backtracking(statements, player+1, good+new_good, bad+new_bad)\n",
    "            if i not in bad:\n",
    "                bad.append(i)\n",
    "        \n",
    "        if len(set(good).intersection(set(bad))) > 0:\n",
    "            pass \n",
    "        else: \n",
    "            self.max_total = max(len(good), self.max_total)\n",
    "        return \n",
    "                    \n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        self.backtracking(statements, 0, [], [])\n",
    "        return self.max_total \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        n = len(statements)\n",
    "        ret = 0\n",
    "        for status in range(1 << n):\n",
    "            good = [0] * n\n",
    "            cnt = 0\n",
    "            for i in range(n):\n",
    "                if status & 1 << i:\n",
    "                    good[i] = 1\n",
    "                    cnt += 1\n",
    "            for i in range(n):\n",
    "                g = good[i]\n",
    "                if not g:\n",
    "                    continue\n",
    "                flag = 0\n",
    "                for j in range(n):\n",
    "                    if i == j:\n",
    "                        continue\n",
    "                    g2 = good[j] == statements[i][j] or statements[i][j] == 2\n",
    "                    if not g2:\n",
    "                        flag = 1\n",
    "                        break\n",
    "                if flag:\n",
    "                    break\n",
    "            else:\n",
    "                ret = max(ret, cnt)\n",
    "        return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        N = len(statements)\n",
    "        known = [-1] * N\n",
    "        ans = 0\n",
    "\n",
    "        def traceback(p):\n",
    "            nonlocal ans, known\n",
    "            if p == N: \n",
    "                ans = max(ans, known.count(True))\n",
    "                return\n",
    "            \n",
    "            known_ = known.copy()\n",
    "\n",
    "            if known[p] is False: \n",
    "                traceback(p + 1)\n",
    "            elif known[p] is True:\n",
    "                for idx, s in enumerate(statements[p]):\n",
    "                    if s == 0:\n",
    "                        if known[idx] is True: return\n",
    "                        else: known[idx] = False\n",
    "                    elif s == 1:\n",
    "                        if known[idx] is False: return\n",
    "                        else: known[idx] = True\n",
    "            \n",
    "                traceback(p + 1)\n",
    "                known = known_\n",
    "            else:\n",
    "                \n",
    "                known[p] = False\n",
    "                traceback(p + 1)\n",
    "                \n",
    "                known = known_\n",
    "                known[p] = True\n",
    "                for idx, s in enumerate(statements[p]):\n",
    "                    if s == 0:\n",
    "                        if known[idx] is True: return\n",
    "                        else: known[idx] = False\n",
    "                    elif s == 1:\n",
    "                        if known[idx] is False: return\n",
    "                        else: known[idx] = True\n",
    "            \n",
    "                traceback(p + 1)\n",
    "                known = known_\n",
    "            \n",
    "\n",
    "        traceback(0)\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        n = len(statements)\n",
    "\n",
    "        def check(f):  # 0: bad, 1: good\n",
    "            for i in range(n):\n",
    "                if f & (1 << i) == 0: continue\n",
    "                for j in range(n):\n",
    "                    if statements[i][j] == 2: continue\n",
    "                    if statements[i][j] != ((f >> j) & 1):\n",
    "                        return False\n",
    "            return True\n",
    "\n",
    "        ans = 0\n",
    "        for i in range(1 << n):\n",
    "            if check(i):\n",
    "                ans = max(ans, i.bit_count())\n",
    "        return ans\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        n = len(statements) \n",
    "        ans = 0 \n",
    "        for i in range(1 << n):\n",
    "            flag = 1\n",
    "            cnt= 0 \n",
    "            for j in range(n):\n",
    "                if (i >> j) & 1:\n",
    "                    for k in range(n):\n",
    "                        if (statements[j][k] == 1 and (i >> k) & 1 == 0) or (statements[j][k] == 0 and (i>>k)&1 == 1):\n",
    "                            flag = 0\n",
    "                            break\n",
    "                    if flag == 0:\n",
    "                        break \n",
    "                    cnt += 1\n",
    "            if flag: \n",
    "                ans = max(ans, cnt) \n",
    "        return ans "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        N = len(statements)\n",
    "        known = [-1] * N\n",
    "        ans = 0\n",
    "\n",
    "        def traceback(p):\n",
    "            nonlocal ans, known\n",
    "            if p == N: \n",
    "                ans = max(ans, known.count(True))\n",
    "                return\n",
    "            \n",
    "            known_ = known.copy()\n",
    "\n",
    "            if known[p] is False: \n",
    "                traceback(p + 1)\n",
    "            elif known[p] is True:\n",
    "                for idx, s in enumerate(statements[p]):\n",
    "                    if s == 0:\n",
    "                        if known[idx] is True: return\n",
    "                        else: known[idx] = False\n",
    "                    elif s == 1:\n",
    "                        if known[idx] is False: return\n",
    "                        else: known[idx] = True\n",
    "            \n",
    "                traceback(p + 1)\n",
    "                # known = known_\n",
    "            else:\n",
    "                \n",
    "                known[p] = False\n",
    "                traceback(p + 1)\n",
    "\n",
    "                known = known_\n",
    "                known[p] = True\n",
    "                for idx, s in enumerate(statements[p]):\n",
    "                    if s == 0:\n",
    "                        if known[idx] is True: return\n",
    "                        else: known[idx] = False\n",
    "                    elif s == 1:\n",
    "                        if known[idx] is False: return\n",
    "                        else: known[idx] = True\n",
    "            \n",
    "                traceback(p + 1)\n",
    "                # known = known_\n",
    "            \n",
    "\n",
    "        traceback(0)\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\r\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\r\n",
    "        def check(i: int) -> int:\r\n",
    "            cnt = 0  # i 中好人个数\r\n",
    "            for j, row in enumerate(statements):  # 枚举 i 中的好人 j\r\n",
    "                if (i >> j) & 1:\r\n",
    "                    if any(st < 2 and st != (i >> k) & 1 for k, st in enumerate(row)):\r\n",
    "                        return 0  # 好人 j 的某个陈述 st 与实际情况矛盾\r\n",
    "                    cnt += 1\r\n",
    "            return cnt\r\n",
    "\r\n",
    "        return max(check(i) for i in range(1, 1 << len(statements)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        n = len(statements)\n",
    "        ifgood = [2] * n # 表示n个人都不知道是好是坏\n",
    "        val = func1(statements, ifgood)\n",
    "        return max(0, val)\n",
    "        \n",
    "def sayifgood(statements, lstgood, x, flg):\n",
    "    cur = lstgood[x]\n",
    "    if cur == flg:\n",
    "        return True\n",
    "    if cur != 2:\n",
    "        return False\n",
    "    lstgood[x] = flg\n",
    "    if flg == 1: # 我是好人，我说话才有用\n",
    "        for i, how in enumerate(statements[x][:x]): # 我怎么说其他人\n",
    "            if how == 0:\n",
    "                if lstgood[i] == 0:\n",
    "                    continue\n",
    "                elif lstgood[i] == 1:\n",
    "                    return False\n",
    "                if not sayifgood(statements, lstgood, i, 0):\n",
    "                    return False   # 我说他是坏人，他就是坏人\n",
    "            elif how == 1:\n",
    "                if lstgood[i] == 1:\n",
    "                    continue\n",
    "                elif lstgood[i] == 0:\n",
    "                    return False\n",
    "                if not sayifgood(statements, lstgood, i, 1):\n",
    "                    return False   # 我说他是好人，他就是好人\n",
    "            else:\n",
    "                assert how == 2 # do nothing, 我没说他\n",
    "    # 看看别人怎么说我\n",
    "    for i in range(x):\n",
    "        how = statements[i][x]\n",
    "        if how == 2:\n",
    "            continue\n",
    "        if how != flg: # 谁说错我了，都是坏人\n",
    "            if not sayifgood(statements, lstgood, i, 0):\n",
    "                return False   # 我说他是坏人，他就是坏人\n",
    "    return True\n",
    "\n",
    "def func1(statements, ifgood):\n",
    "    n = len(ifgood)\n",
    "    if n == 0:\n",
    "        return 0\n",
    "    howlast = ifgood[-1]\n",
    "    if howlast == 0: # 最后一人是坏人\n",
    "        return func1(statements, ifgood[:n-1])\n",
    "    if howlast == 1: # 最后一人是好人\n",
    "        return 1 + func1(statements, ifgood[:n-1])\n",
    "    assert howlast == 2 # 最后一人未确认\n",
    "\n",
    "    n3 = -15; n4 = -15\n",
    "    # 先假定他是好人\n",
    "    ifgood1 = ifgood[:]\n",
    "    if sayifgood(statements, ifgood1, n-1, 1):\n",
    "        n3 = 1 + func1(statements, ifgood1[:n-1])\n",
    "    # 再假定他是坏人\n",
    "    ifgood2 = ifgood[:]\n",
    "    if sayifgood(statements, ifgood2, n-1, 0):\n",
    "        n4 = func1(statements, ifgood2[:n-1])\n",
    "    return max(n3,n4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        n = len(statements)\n",
    "\n",
    "        # 指责对方为坏人，则不可能同时为好人\n",
    "        dislike = [set() for _ in range(n)]\n",
    "        for i in range(n):\n",
    "            for j in range(n):\n",
    "                if statements[i][j] == 0:\n",
    "                    dislike[i].add(j)\n",
    "                    dislike[j].add(i)\n",
    "        # 对于同一个人j的判断结果不同，则不可能同时为好人\n",
    "        for j in range(n):\n",
    "            good = []\n",
    "            bad = []\n",
    "            for i in range(n):\n",
    "                if statements[i][j] == 0:\n",
    "                    bad.append(i)\n",
    "                if statements[i][j] == 1:\n",
    "                    good.append(i)\n",
    "            for x in good:\n",
    "                for y in bad:\n",
    "                    dislike[x].add(y)\n",
    "                    dislike[y].add(x)\n",
    "\n",
    "        # 认为对方是好人，则必须同时都是好人\n",
    "        like = [set() for _ in range(n)]\n",
    "        for i in range(n):\n",
    "            for j in range(n):\n",
    "                if statements[i][j] == 1:\n",
    "                    like[i].add(j)\n",
    "\n",
    "        def check():\n",
    "            # 判断不存在不可能同时为好人的组合\n",
    "            for x in lst:\n",
    "                for y in dislike[x]:\n",
    "                    if y in lst:\n",
    "                        return False\n",
    "            # 判断必须同时为好人的组合\n",
    "            for x in lst:\n",
    "                for y in like[x]:\n",
    "                    if y not in lst:\n",
    "                        return False\n",
    "            return True\n",
    "\n",
    "        # 使用状态压缩进行枚举\n",
    "        ans = 0\n",
    "        for i in range(1, 1 << n):\n",
    "            lst = set([j for j in range(n) if i & (1 << j)])\n",
    "            m = len(lst)\n",
    "            if check() and m > ans:\n",
    "                ans = m\n",
    "        return ans\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        res = 0\n",
    "        n = len(statements)\n",
    "        m = 2 ** n\n",
    "        good = [False] * n\n",
    "        for x in range(m):\n",
    "            count = 0\n",
    "            for i in range(n):\n",
    "                if x % 2 == 1:\n",
    "                    good[i] = True\n",
    "                    count += 1\n",
    "                else:\n",
    "                    good[i] = False\n",
    "                x //= 2\n",
    "            if count > res and self.verify(statements, good):\n",
    "                res = count\n",
    "        return res\n",
    "\n",
    "    def verify(self, statements: List[List[int]], good: List[bool]) -> bool:\n",
    "        n = len(statements)\n",
    "        for i in range(n):\n",
    "            if good[i]:\n",
    "                for j in range(n):\n",
    "                    if good[j] and statements[i][j] == 0:\n",
    "                        return False\n",
    "                    if not good[j] and statements[i][j] == 1:\n",
    "                        return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        n = len(statements)\n",
    "\n",
    "        def check(combin):\n",
    "            for i in combin:\n",
    "                for j in range(n):\n",
    "                    if (statements[i][j] == 0 and j in combin) or (statements[i][j] == 1 and j not in combin):\n",
    "                        return False\n",
    "            return True\n",
    "\n",
    "        for l in range(n, 0, -1):\n",
    "            for combin in combinations(range(n), l):\n",
    "                if check(combin):\n",
    "                    return l\n",
    "\n",
    "        return 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from typing import List\n",
    "from itertools import combinations\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        n = len(statements)\n",
    "        \n",
    "        def check(good_set):\n",
    "            for i in good_set:\n",
    "                for j in range(n):\n",
    "                    if j == i:\n",
    "                        continue\n",
    "                    if statements[i][j] == 0 and j in good_set:\n",
    "                        return False\n",
    "                    if statements[i][j] == 1 and j not in good_set:\n",
    "                        return False\n",
    "            return True\n",
    "\n",
    "        max_good = 0\n",
    "        for size in range(1, n + 1):\n",
    "            for good_set in combinations(range(n), size):\n",
    "                if check(good_set):\n",
    "                    max_good = max(max_good, size)\n",
    "        \n",
    "        return max_good\n",
    "\n",
    "# 测试\n",
    "sol = Solution()\n",
    "print(sol.maximumGood([[1, 0], [1, 1]]))  # 应输出 1\n",
    "print(sol.maximumGood([[1, 0, 0], [2, 1, 0], [1, 1, 1]]))  # 应输出 2\n",
    "print(sol.maximumGood([[0, 0], [0, 1]]))  # 应输出 0\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        n = len(statements)\n",
    "        judge_lst = [2] * n\n",
    "        num = func1(judge_lst,statements)\n",
    "        return num\n",
    "\t\n",
    "def func1(judge_lst,statements):\n",
    "\tn = len(judge_lst)\n",
    "\tif n == 0:\n",
    "\t\treturn 0\n",
    "\t\t\n",
    "\tif judge_lst[-1] == 1:\n",
    "\t\treturn 1 + func1(judge_lst[:-1],statements)\n",
    "\tif judge_lst[-1] == 0:\n",
    "\t\treturn func1(judge_lst[:-1],statements)\n",
    "\t\n",
    "\tnum1 = num2 = -15\n",
    "\t# 假设是好人\n",
    "\tlst1 = judge_lst[:]\n",
    "\tif sayifgood(statements, lst1, n - 1, 1):\n",
    "\t\tnum1 = 1 + func1(lst1[:-1],statements)\n",
    "\t\t\n",
    "\t# 假设是坏人\n",
    "\tlst2 = judge_lst[:]\n",
    "\tif sayifgood(statements, lst2, n - 1, 0):\n",
    "\t\tnum2 = func1(lst2[:-1],statements)\n",
    "\t\n",
    "\t# 如果都矛盾\n",
    "\treturn max(num1,num2)\n",
    "\t\n",
    "def sayifgood(statements, lstgood, x, flg):\n",
    "    cur = lstgood[x]\n",
    "    if cur == flg:\n",
    "        return True\n",
    "    if cur != 2:\n",
    "        return False\n",
    "    lstgood[x] = flg\n",
    "    if flg == 1:  # 我是好人，我说话才有用\n",
    "        for i, how in enumerate(statements[x][:x]):  # 我怎么说其他人\n",
    "            if how == 0:\n",
    "                if lstgood[i] == 0:\n",
    "                    continue\n",
    "                elif lstgood[i] == 1:\n",
    "                    return False\n",
    "                if not sayifgood(statements, lstgood, i, 0):\n",
    "                    return False  # 我说他是坏人，他就是坏人\n",
    "            elif how == 1:\n",
    "                if lstgood[i] == 1:\n",
    "                    continue\n",
    "                elif lstgood[i] == 0:\n",
    "                    return False\n",
    "                if not sayifgood(statements, lstgood, i, 1):\n",
    "                    return False  # 我说他是好人，他就是好人\n",
    "            else:\n",
    "                assert how == 2  # do nothing, 我没说他\n",
    "    # 看看别人怎么说我\n",
    "    for i in range(x):\n",
    "        how = statements[i][x]\n",
    "        if how == 2:\n",
    "            continue\n",
    "        if how != flg:  # 谁说错我了，都是坏人\n",
    "            if not sayifgood(statements, lstgood, i, 0):\n",
    "                return False  # 我说他是坏人，他就是坏人\n",
    "    return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        n = len(statements)\n",
    "\n",
    "        def check(mask):\n",
    "            for i in range(n):\n",
    "                if not mask >> i & 1:\n",
    "                    continue\n",
    "                for j in range(n):\n",
    "                    if statements[i][j] == 2:\n",
    "                        continue\n",
    "                    if statements[i][j] ^ (mask >> j & 1):\n",
    "                        return False\n",
    "            return True\n",
    "\n",
    "        ans = 0\n",
    "        for mask in range(1, 1<<n):\n",
    "            if check(mask):\n",
    "                ans = max(ans, mask.bit_count())\n",
    "        return ans\n",
    "                   "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        def check(i):\n",
    "            n = len(statements)\n",
    "            cnt = 0\n",
    "            for j in range(n):\n",
    "                if i >> j & 1:\n",
    "                    for k, x in enumerate(statements[j]):\n",
    "                        if x < 2 and i >> k & 1 != x:\n",
    "                            return 0\n",
    "                    cnt += 1\n",
    "            return cnt\n",
    "        return max(check(x) for x in range(1, 1 << len(statements)))                  \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        n = len(statements)\n",
    "        res = 0\n",
    "        for mask in range(1 << n):\n",
    "            isGood = [False] * n\n",
    "            for i in range(n):\n",
    "                isGood[i] = mask & 1 == 1\n",
    "                mask >>= 1\n",
    "            flag = True\n",
    "            for i in range(n):\n",
    "                if isGood[i]:\n",
    "                    for j in range(n):\n",
    "                        if (statements[i][j] == 0 and isGood[j]) or (statements[i][j] == 1 and not isGood[j]):\n",
    "                            flag = False\n",
    "                            break\n",
    "                    if not flag:\n",
    "                        break\n",
    "            if flag:\n",
    "                res = max(res, sum(isGood))\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        \n",
    "        def check():\n",
    "            for x in good:\n",
    "                for y in range(n):\n",
    "                    w = statements[x][y]\n",
    "                    if w == 2:\n",
    "                        continue\n",
    "                    if w == 1 and y not in good:\n",
    "                        return False\n",
    "                    if w == 0 and y not in bad:\n",
    "                        return False\n",
    "            return True\n",
    "                    \n",
    "        n = len(statements)\n",
    "        ans = 0\n",
    "        for i in range(1, 1<<n):\n",
    "            good = set([j for j in range(n) if i & (1<<j)])\n",
    "            bad = set([j for j in range(n) if not i & (1<<j)])\n",
    "            if check() and len(good) > ans:\n",
    "                ans = len(good)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from typing import List\n",
    "from itertools import combinations\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        n = len(statements)\n",
    "        \n",
    "        def check(good_set):\n",
    "            for i in good_set:\n",
    "                for j in range(n):\n",
    "                    if j == i:\n",
    "                        continue\n",
    "                    if statements[i][j] == 0 and j in good_set:\n",
    "                        return False\n",
    "                    if statements[i][j] == 1 and j not in good_set:\n",
    "                        return False\n",
    "            return True\n",
    "\n",
    "        max_good = 0\n",
    "        for size in range(1, n + 1):\n",
    "            for good_set in combinations(range(n), size):\n",
    "                if check(good_set):\n",
    "                    max_good = max(max_good, size)\n",
    "        \n",
    "        return max_good\n",
    "\n",
    "# 测试\n",
    "sol = Solution()\n",
    "print(sol.maximumGood([[1, 0], [1, 1]]))  # 应输出 1\n",
    "print(sol.maximumGood([[1, 0, 0], [2, 1, 0], [1, 1, 1]]))  # 应输出 2\n",
    "print(sol.maximumGood([[0, 0], [0, 1]]))  # 应输出 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        n = len(statements)\n",
    "        judge_lst = [2] * n\n",
    "        num = func1(judge_lst,statements)\n",
    "        return num\n",
    "\t\n",
    "def func1(judge_lst,statements):\n",
    "\tn = len(judge_lst)\n",
    "\tif n == 0:\n",
    "\t\treturn 0\n",
    "\t\t\n",
    "\tif judge_lst[-1] == 1:\n",
    "\t\treturn 1 + func1(judge_lst[:-1],statements)\n",
    "\tif judge_lst[-1] == 0:\n",
    "\t\treturn func1(judge_lst[:-1],statements)\n",
    "\t\n",
    "\tnum1 = num2 = -15\n",
    "\t# 假设是好人\n",
    "\tlst1 = judge_lst[:]\n",
    "\tif sayifgood(statements, lst1, n - 1, 1):\n",
    "\t\tnum1 = 1 + func1(lst1[:-1],statements)\n",
    "\t\t\n",
    "\t# 假设是坏人\n",
    "\tlst2 = judge_lst[:]\n",
    "\tif sayifgood(statements, lst2, n - 1, 0):\n",
    "\t\tnum2 = func1(lst2[:-1],statements)\n",
    "\t\n",
    "\t# 如果都矛盾\n",
    "\treturn max(num1,num2)\n",
    "\t\n",
    "def sayifgood(statements, lstgood, x, flg):\n",
    "    cur = lstgood[x]\n",
    "    if cur == flg:\n",
    "        return True\n",
    "    if cur != 2:\n",
    "        return False\n",
    "    lstgood[x] = flg\n",
    "    if flg == 1:  # 我是好人，我说话才有用\n",
    "        for i, how in enumerate(statements[x][:x]):  # 我怎么说其他人\n",
    "            if how == 0:\n",
    "                if lstgood[i] == 0:\n",
    "                    continue\n",
    "                elif lstgood[i] == 1:\n",
    "                    return False\n",
    "                if not sayifgood(statements, lstgood, i, 0):\n",
    "                    return False  # 我说他是坏人，他就是坏人\n",
    "            elif how == 1:\n",
    "                if lstgood[i] == 1:\n",
    "                    continue\n",
    "                elif lstgood[i] == 0:\n",
    "                    return False\n",
    "                if not sayifgood(statements, lstgood, i, 1):\n",
    "                    return False  # 我说他是好人，他就是好人\n",
    "            else:\n",
    "                assert how == 2  # do nothing, 我没说他\n",
    "    # 看看别人怎么说我\n",
    "    for i in range(x):\n",
    "        how = statements[i][x]\n",
    "        if how == 2:\n",
    "            continue\n",
    "        if how != flg:  # 谁说错我了，都是坏人\n",
    "            if not sayifgood(statements, lstgood, i, 0):\n",
    "                return False  # 我说他是坏人，他就是坏人\n",
    "    return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from math import *\n",
    "from queue import PriorityQueue,Queue\n",
    "from typing import *\n",
    "from heapq import *\n",
    "from functools import lru_cache\n",
    "from string import *\n",
    "# by hangpengjie\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        n = len(statements)\n",
    "        res = 0\n",
    "        def check(mask:int)->bool:\n",
    "            for i in range(n):\n",
    "                # i是好人，他的话有用\n",
    "                if (1 << i) & mask:\n",
    "                    for j in range(n):\n",
    "                        # i有判断j是好人还是好人\n",
    "                        if statements[i][j] < 2:\n",
    "                            # i的判断结果有误，则mask这种情况不正确\n",
    "                            if (mask >> j) & 1 ^ statements[i][j]:\n",
    "                                return False\n",
    "            return True\n",
    "        for i in range(1<<n):\n",
    "            if check(i):\n",
    "                res = max(res,i.bit_count())\n",
    "    \n",
    "        return res\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximumGood(self, statements: List[List[int]]) -> int:\n",
    "        N = len(statements)\n",
    "        known = [-1] * N\n",
    "        ans = 0\n",
    "\n",
    "        def traceback(p):\n",
    "            nonlocal ans, known\n",
    "            if p == N: \n",
    "                ans = max(ans, known.count(True))\n",
    "                return\n",
    "\n",
    "            if known[p] is False: \n",
    "                traceback(p + 1)\n",
    "            elif known[p] is True:\n",
    "                for idx, s in enumerate(statements[p]):\n",
    "                    if s == 0:\n",
    "                        if known[idx] is True: return\n",
    "                        else: known[idx] = False\n",
    "                    elif s == 1:\n",
    "                        if known[idx] is False: return\n",
    "                        else: known[idx] = True\n",
    "            \n",
    "                traceback(p + 1)\n",
    "            else:\n",
    "                known_ = known.copy()\n",
    "                known[p] = False\n",
    "                traceback(p + 1)\n",
    "\n",
    "                known = known_\n",
    "                known[p] = True\n",
    "                for idx, s in enumerate(statements[p]):\n",
    "                    if s == 0:\n",
    "                        if known[idx] is True: return\n",
    "                        else: known[idx] = False\n",
    "                    elif s == 1:\n",
    "                        if known[idx] is False: return\n",
    "                        else: known[idx] = True\n",
    "            \n",
    "                traceback(p + 1)\n",
    "            \n",
    "\n",
    "        traceback(0)\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# ref: https://leetcode.cn/problems/maximum-height-by-stacking-cuboids/solutions/2014514/tu-jie-suan-fa-you-hua-xiang-xi-zheng-mi-b6fq/\n",
    "# 为什么可以直接加最长边？ - 因为堆的时候就是“长对长，中对中，短对短”\n",
    "# O(n**2), O(n)\n",
    "class Solution:\n",
    "    def maxHeight(self, cuboids: List[List[int]]) -> int:\n",
    "        n = len(cuboids)\n",
    "        if n == 1:\n",
    "            return max(cuboids[0])\n",
    "\n",
    "        dp = [0] * n\n",
    "\n",
    "        for c in cuboids:\n",
    "            c.sort(reverse = True)  \n",
    "        cuboids = sorted(cuboids,key = lambda x: (x[0],x[1],x[2]),reverse = True)\n",
    "\n",
    "        for i,(w1,l1,h1) in enumerate(cuboids):\n",
    "            for j,(w2,l2,h2) in enumerate(cuboids[:i]):\n",
    "                if w2 >= w1 and l2 >= l1 and h2 >= h1:\n",
    "                    dp[i] = max(dp[i],dp[j])\n",
    "            dp[i] += w1\n",
    "        return max(dp)\n",
    "\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return max([a,b])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return max(a,b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        #return max(a, b)\n",
    "        return (a+b+abs(a-b)) // 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return (abs(a-b)+a+b)//2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        q = [a,b]\n",
    "        q.sort()\n",
    "        return q[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return (a+b+abs(a-b))//2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return max(a,b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return max(a,b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        list=[a,b]\n",
    "        list.sort()\n",
    "        return list[1]\n",
    "\n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        try:\n",
    "            int(str(a-b)[0])\n",
    "        except:\n",
    "            return b\n",
    "        return a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return max(a, b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return max(a,b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return ((a+b) + abs(a-b)) // 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return max(a,b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "      k = ((a - b ) >> 63 ) & 1\n",
    "      print(k)\n",
    "      return k * b + a * (k^1) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return a if a > b else b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return a if (a - b) >> 33 == 0 else b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        k = ((a-b)>>33)&1\n",
    "        return a*(1-k)+b*k\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "       return max(a,b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        # return ((a+b+abs(a-b))//2)\n",
    "        try:\n",
    "            int(str(a-b)[0])\n",
    "        except:\n",
    "            return b\n",
    "        return a\n",
    "        # sign = ((a-b)>>31)&1\n",
    "        # print(sign,len(bin(a-b)))\n",
    "        # return a-sign*(a-b)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        list=[a,b]\n",
    "        list.sort()\n",
    "        return list[1]\n",
    "\n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return max([a, b])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return max(a, b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return ((a+b+abs(a-b))//2)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return max(a,b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    # max(a,b) = a if a >= b else b\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return a * (a >= b) or b\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "       return a > b and a or b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return [a, b][(a//2 - b//2) >> 31]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "\tdef maximum(self, a: int, b: int) -> int:\n",
    "\t\treturn max(a, b)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "import math\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return int((math.fabs(a-b) + a + b)/2)\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        if a > b:\n",
    "            return a\n",
    "        else:\n",
    "            return b\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return max(a,b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from math import *\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        max_num=(abs(a-b)+a+b)//2\n",
    "        return max_num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a, b):\n",
    "        list = []\n",
    "        for i in (a, b):\n",
    "            list.append(i)\n",
    "        return max(list)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        k = ((a - b) >> 32) & 1\n",
    "        return b * k + a * (k ^ 1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return a if a>b else b\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return a if a>b else b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return max(a,b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return max(a,b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return max(a,b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return max(a, b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return int(abs(b-a)/2+(a+b)/2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        # return max(a,b)\n",
    "\n",
    "        # 2. \n",
    "        return int((a+b + abs(a-b)) /2)\n",
    "        \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return a if a>b else b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return max(a,b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return int((math.fabs(a-b) + a + b)/2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        c=a-b\n",
    "        c=c>>63\n",
    "        return (c+1)*a-c*b\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return max(a, b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return (a+b+abs(a-b)) // 2\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        if a-b>0:\n",
    "            return a\n",
    "        else:\n",
    "            return b\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return max(a,b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        # k = ((a - b) >> 32) & 1\n",
    "        # return b * k + a * (k ^ 1)\n",
    "        return max(a, b)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return max(a,b)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "       return a if a>b else b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        if str(a-b)[0]=='-':\n",
    "            return b\n",
    "        return a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maximum(self, a: int, b: int) -> int:\n",
    "        return (a + b + abs(a - b)) // 2"
   ]
  }
 ],
 "metadata": {},
 "nbformat": 4,
 "nbformat_minor": 2
}
